signals icon indicating copy to clipboard operation
signals copied to clipboard

Creating a empty signal and updating it make the application stop re-rendering

Open fbzz opened this issue 2 years ago • 4 comments

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>
    </>
  );
}

fbzz avatar Sep 26 '23 11:09 fbzz

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.

monaye avatar Nov 02 '23 06:11 monaye

Same issue here, when you init signal with an empty array

  1. With useSignal([]) syntax, it cannot update value, it shows "Cannot read properties of undefined (reading 'length')" error
  2. With signal([]), it only updates at first time, at second time it won't work

namtv95 avatar Dec 01 '23 18:12 namtv95

Can you provide stackblitz repro to check?

XantreDev avatar Dec 02 '23 14:12 XantreDev

Btw, you should not mutate values of signals. Signals doesn't reacting on mutations. Use .toSpliced

XantreDev avatar Dec 02 '23 14:12 XantreDev