首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SolidJS -如何使DOM元素响应于信号更新?

SolidJS -如何使DOM元素响应于信号更新?
EN

Stack Overflow用户
提问于 2022-09-08 22:49:13
回答 2查看 385关注 0票数 0

新手的问题--使用SolidJS,如何使DOM元素响应于信号更新?

我有两个实例无法按预期进行更新。

  1. 在“源”组件中,尝试更新项计数时。
  2. 在远程组件中,尝试更新项结果时。

源组件

代码语言:javascript
复制
import { Component } from 'solid-js'
import { isEqual as _isEqual } from 'lodash-es'

const [getItems, setItems] = createSignal<Array<Item>>([])

const OriginComponent: Component = () => {
    const updateItems = (item: Item) => {
        const init = getItems()
        const index = init.findIndex(i => _isEqual(i, item))

        index == -1 ? init.push(item) : init.splice(index, 1)

        setItems(init)
    }

    return (
        <>
            <span>Item Count: {getItems().length}</span> //       << -- WILL NOT CHANGE.
            <button onclick={() => updateItems(x: Item)}>Click Me</button>
        </>
    )
}

export { OriginComponent, getItems }

远程组件

代码语言:javascript
复制
import { Component } from 'solid-js'
import { getItems } from '../OriginComponent'

const RemoteComponent: Component = () => {
    return (
        <p class='results'>
            {getItems() ? 'Has Items' : 'Has No Items'} //        << -- WILL NOT CHANGE.
        </p>
    )
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-09 02:44:06

根据Solid的API文档 for createSignal (在options部分):

根据JavaScript的===操作符,默认情况下,在调用信号的setter时,如果新值实际上与旧值不同,则信号只更新(并导致依赖方重新运行)。

这里就是这种情况,因为在信号中设置的数组与旧的数组相同(===)。解决方法之一是为信号设置关闭引用相等检查,如:createSignal<Array<Item>>([], { equals: false })

另一个选项是在再次设置数组时创建一个新数组,如下所示:setItems([...init])

票数 2
EN

Stack Overflow用户

发布于 2022-09-11 06:03:14

组件不是DOM元素,它们在编译过程中被编译成DOM元素,但是它们有额外的可重用性。

您正在尝试更改数组,但是信号的工作方式是需要设置一个新的数组来触发状态更新。

代码语言:javascript
复制
const [items, setItems] = createSignal([]);

setInterval(() => {
  setItems([ ...items(), items().length ]);
}, 1000);

因此,设置一个新数组并遵循JSX规则将足以解决您的问题。

现在,为了提出这个问题,未来的证据让我们看看如何更新实体系统之外的实际DOM元素。

首先,我将创建一个DOM元素并将其附加到主体中,但是对于已经存在的DOM元素,该机制将同样工作。

代码语言:javascript
复制
import { createSignal, createEffect } from "solid-js";

// Get the DOM element
const el = document.createElement('div');
document.querySelector('body').appendChild(el);

// Signal that will be the content of our DOM element
const [count, setCount] = createSignal(0);

// I will use setInterval to update the signal for simplicity
setInterval(() => {
  setCount(c => c + 1);
}, 1000);

// I will create an effect to update the element's innerText or innerHTML
// whenever the signal updates.
createEffect(() => {
  el.innerHTML = count();
});

在这里,我们的解决方案有一个小问题,我们创建的效果不会被任何跟踪范围所拥有,所以当它的作用域被释放时,它可能不会被释放。

最好在render函数中运行这段代码,该函数自动创建根,或者自己使用createRoot创建根,并在不需要时将其释放。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73655691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档