I'm just trying to get to grips with Preact Signals so maybe I'm doing something wrong but I'm trying to allow the user to update a value but whenever they do it just reverts back to the default value. If I log it, it does show the changed value but immediately reverts back. Am I missing something?
我只是试图理解Preact信号,所以可能我做错了什么,但我试图允许用户更新一个值,但每当他们这样做时,它就会恢复到缺省值。如果我将其记录下来,它确实会显示更改后的值,但会立即恢复。我是不是遗漏了什么?
So in the case below the input for reps is initially 10. If the user changes it, it will log the new value as well as new computed value but immediately return back to 10.
因此,在下面的例子中,reps的输入最初是10。如果用户更改了它,它将记录新的值以及新的计算值,但立即返回到10。
Thanks in advance
提前谢谢你
import { signal, computed } from "@preact/signals";
export default function SetInput({ setNo }: { setNo: number }) {
const state = signal({
reps: 10,
weight: 20,
});
const volume = computed(() => state.value.reps * state.value.weight);
const onHandleChange = (event: any) => {
const { name, value } = event.target;
state.value = { ...state.value, [name]: parseInt(value) };
console.log(name, value, state.value.reps, volume.value);
};
return (
<div class="flex flex-row gap-8 mx-auto">
<div>
<label
html-for={`s${setNo}-reps`}
class="block text-md text-gray-400 opacity-85 mb-2"
>
Reps
</label>
<input
name="reps"
type="number"
id={`s${setNo}-reps`}
value={state.value.reps}
class="shadow appearance-none border w-24 rounded py-2 px-3 text-gray-700"
onChange={onHandleChange}
/>
</div>
<div>
<label
html-for={`s${setNo}-weight`}
class="block text-md text-gray-400 opacity-85 mb-2"
>
Weight
</label>
<input
name="weight"
type="number"
id={`s${setNo}-weight`}
value={state.value.weight}
class="shadow appearance-none border w-24 rounded py-2 px-3 text-gray-700"
onChange={onHandleChange}
/>
</div>
<div>
<span
html-for={`s${setNo}-reps`}
class="block text-md text-gray-400 opacity-85 mb-2"
>
Volume
</span>
<span class="">{volume.value}</span>
</div>
</div>
);
}
更多回答
优秀答案推荐
You cannot use signal
or computed
inside components -- on every render, these will reset. Use the hook-like versions instead: useSignal
& useComputed
. Exact same API, so you don't need to make any changes other than the imports & function names.
不能在组件内部使用signal或computed--在每次渲染时,这些都将重置。使用类似钩子的版本:useSignal & useComputed。完全相同的API,所以除了导入和函数名称之外,您不需要进行任何更改。
Alternatively, move the signal
& computed
outside of your component.
或者,将信号& calculated移到组件之外。
When creating signals within a component, use the hook variant: useSignal(initialValue).
Docs
多科
更多回答
I was literally just typing to say I discovered the same thing myself when you posted. I did initially change it to useSignal/useComputed although have now moved it to a global state as that was ultimately the goal, just wanted to start off with something small to get to grips. Thank you.
当你发帖时,我只是打字想说我自己也发现了同样的事情。我最初确实将其更改为使用Signal/useComputed,尽管现在已将其移动到全局状态,因为这是最终目标,我只是想从一些小的东西开始掌握。谢谢。
我是一名优秀的程序员,十分优秀!