在下面的最小示例中,我想在单击事件之后更改按钮的文本。 已单击的按钮 ID 存储在信号内的集合中。当集合更改时,不会触发 dom-update。
我做错了什么?
import { render } from 'preact';
import { signal, effect } from "@preact/signals-core";
export function App() {
const selected = signal(new Set<number>);
const onClick = (index) =>{
console.log("click" + index +" current state:"+ selected.value.has(index))
const s = new Set(selected.value)
if(selected.value.has(index))
s.delete(index)
else
s.add(index)
selected.value = s
}
return (
<div>
<div>
{new Array(10).fill(0).map((_, index) => (
<button type="button" onClick={() => onClick(index)}>
{selected.value.has(index)+""}
</button>
))}
</div>
</div>
);
}
render(<App />, document.getElementById('app'));
首先,您应该在 Preact 应用程序中使用
@preact/signals
,而不是 @preact/signals-core
。前者添加了您需要的绑定。
其次,您不能在组件内部使用
signal
。如果您无法提取信号创建,请使用 useSignal()
。
在组件内创建信号时,请使用钩子变体:
。useSignal(initialValue)
https://preactjs.com/guide/v10/signals#signalinitialvalue
之后,它应该可以工作:
import { render } from 'preact';
import { useSignal } from '@preact/signals';
export function App() {
const selected = useSignal(new Set<number>);
const onClick = (index) => {
console.log(
'click' + index + ' current state:' + selected.value.has(index)
);
const s = new Set(selected.value);
if (selected.value.has(index)) s.delete(index);
else s.add(index);
selected.value = s;
};
return (
<div>
<div>
{new Array(10).fill(0).map((_, index) => (
<button type="button" onClick={() => onClick(index)}>
{selected.value.has(index) + ''}
</button>
))}
</div>
</div>
);
}
render(<App />, document.getElementById('app'));