immerjs / immer

Create the next immutable state by mutating the current one
https://immerjs.github.io/immer/
MIT License
27.71k stars 849 forks source link

Set never changed with ReactHooks #359

Closed lovelope closed 5 years ago

lovelope commented 5 years ago

🐛 Bug Report

I inited a Set and produce it, but it`s value never changed.

To Reproduce

function App() {
  const [list, setList] = useState<ReadonlySet<number>>(new Set());

  function handleClick(id) {
    console.info(id);
    const nextState = produce(list, (draft: Draft<ReadonlySet<number>>) => {
      console.info("draft", draft);
      const newSet = new Set(draft as Set<number>);
      newSet.add(id);
      draft = newSet;
    });

    console.info("next", nextState);
    setList(nextState);
  }
  return (
    <div className="App">
      <ul>
        {[1, 2, 3, 4].map(item => (
          <li key={item} onClick={() => handleClick(item)}>
            {item}
          </li>
        ))}
      </ul>
    </div>
  );
}

Expected behavior

I expect the set`s value changed.

Link to repro (highly encouraged)

CodeSandbox demo

Environment

aleclarson commented 5 years ago

You need to return newSet instead of draft = newSet.

Note: If that's all you're using produce for, you don't need produce.

lovelope commented 5 years ago

You need to return newSet instead of draft = newSet.

Note: If that's all you're using produce for, you don't need produce.

Thanks. It`s worked. I use it because the real business scenario is more complicated.