signals
signals copied to clipboard
Creating a empty signal and updating it make the application stop re-rendering
So using react with vite, we can even use the example from preact, the first update will work, and after that it will stop
import { signal, computed } from "@preact/signals-react";
const todos = signal([
]);
const completedCount = computed(() => {
return todos.value.filter(todo => todo.completed).length;
});
const newItem = signal("");
function addTodo() {
todos.value = [...todos.value, { text: newItem.value, completed: false }];
newItem.value = ""; // Reset input value on add
}
function removeTodo(index) {
todos.value.splice(index, 1)
todos.value = [...todos.value];
}
function TodoList() {
const onInput = event => (newItem.value = event.target.value);
return (
<>
<input type="text" value={newItem.value} onInput={onInput} />
<button onClick={addTodo}>Add</button>
<ul>
{todos.value.map((todo, index) => {
return (
<li>
<input
type="checkbox"
checked={todo.completed}
onInput={() => {
todo.completed = !todo.completed
todos.value = [...todos.value];
}}
/>
{todo.completed ? <s>{todo.text}</s> : todo.text}{' '}
<button onClick={() => removeTodo(index)}>❌</button>
</li>
);
})}
</ul>
<p>Completed count: {completedCount.value}</p>
</>
);
}
since you are modifying the original array with the splice, I think signal will trigger the re-render. can you try remove the todos.value = [...todos.value]? or try with toSpliced.
Same issue here, when you init signal with an empty array
- With useSignal([]) syntax, it cannot update value, it shows "Cannot read properties of undefined (reading 'length')" error
- With signal([]), it only updates at first time, at second time it won't work
Can you provide stackblitz repro to check?
Btw, you should not mutate values of signals. Signals doesn't reacting on mutations. Use .toSpliced