如何在React Context和Immer本地状态之间共享不可变的数据结构

时间:2019-12-21 01:01:20

标签: javascript reactjs immutability immer.js

如何利用Immer的不可变数据结构来防止在React Provider + Component中不必要的重新渲染?

我有一个包含数据的排序存储,我需要从数据中导出组件局部的状态。我想防止使用useEffect进行不必要的重新渲染,但是据我所知,它每次都在重新渲染。

Pgadmin_capture

我最初的想法是,我可以通过比较arr === arr来根据提供的Context值检查本地沉浸式缓存。这将利用沉浸式的不变性,并且仅在对象不匹配时更新。任何见解均表示赞赏。

上下文更改器

function App() {
  const [store, updateStore] = useImmer({
    count: 0,
    users: { 1: [], 2: [] }
  });
  const clickHandler = () =>
    updateStore(draft => {
      const currentCount = draft.count + 1;
      draft.count = currentCount;
      draft.users["1"].push(currentCount);
    });
  return (
    <div className="App">
      <button type="button" onClick={clickHandler}>
        Increment
      </button>
      <DataProvider {...store}>
        <Child />
      </DataProvider>
    </div>
  );
}

已更新的孩子

function Child() {
  const { users } = useDataStore();
  const [state, updateState] = useImmer({ users: {} });

  function cacheIt(k, arr) {
    console.error("RENDERING ", k);
    updateState(draft => {
      draft.users[k] = arr;
    });
  }

  function update() {
    Object.entries(users).map(user => {
      const [k, arr] = user;
      if (arr !== state[k]) { ///------------> UNEXPECTED BEHAVIOR HERE
        cacheIt(k, arr);
      }
    });
  }

  useEffect(() => {
    update();
  });

  return (
    <div>
      {Object.entries(state.users).map(user => {
        return <Item {...user} />;
      })}
    </div>
  );
}

0 个答案:

没有答案