【问题标题】:React Context will always re-renderReact Context 总是会重新渲染
【发布时间】:2020-03-11 11:29:23
【问题描述】:

如果您在上下文 Provider 值中声明一个对象,则任何上下文消费者在提供者重新渲染时总是会重新渲染,因为每次提供者重新渲染时,value 中的对象都会重新声明。

return (
  <Provider value={{ /* declared object */ }}>{children}</Provider>
);

良好的提供者value 模式

这是一个很好的模式,因为store 只会在setStore 被调用时改变。

// ParentComponent.js

function ParentComponent() {
  const [store, setStore] = useState({ bool: false });

  return (
    <Context.Provider value={store}>
      <button onClick={() => setStore({ ...store, n: { bool: !store.n.bool } })}>
        Switch Bool
      </button>
      <ContextConsumingComponent />
    </Context.Provider>
  );
}

// ContextConsumingComponent.js
function ContextConsumingComponent() {
  const store = useContext(Context);

  console.log('Will only run re-render if the `Switch Bool` button is clicked in parent.');

  return <p>{JSON.stringify(context.bool)}</p>;
}
// Avoid re-renders if props haven't changed.
export default React.memo(ContextConsumingComponent);

错误的提供者value 模式

这是一个糟糕的模式,因为&lt;Provider value={{}} /&gt; 正在侦听对封闭对象的更改,而不是storesetStore 引用本身。现实是我们只想真正听听store

// ParentComponent.js

function ParentComponent() {
  const [store, setStore] = useState({ bool: false });


  return (
    <Context.Provider value={{ store, setStore }}>
      <button onClick={() => setStore({ ...store, n: { bool: !store.n.bool } })}>
        Switch Bool
      </button>
      <ContextConsumingComponent />
    </Context.Provider>
  );
}

问题:

我希望能够在我的上下文消费组件中使用setStore,并且我想了解其他人如何处理这个问题。我相信我可以选择两个提供商选项,但有兴趣看看其他人如何处理这个问题以及如果我错过了任何±。

两个提供者选项:storedispatch

// Two Providers
function ParentComponent() {
  const [store, setStore] = useState({ bool: false });


  return (
    <Store.Provider value={store}>
      <Dispatch.Provider value={setStore}>
        <button onClick={() => setStore({ ...store, n: { bool: !store.n.bool } })}>
          Switch Bool
        </button>
        <ContextConsumingComponent />
      </Dispatch.Provider>
    </Store.Provider>
  );
}

【问题讨论】:

    标签: javascript reactjs react-context


    【解决方案1】:

    我的问题的答案很可能是useMemo

    function App() {
      const [store, setStore] = useState({ bool: false });
    
      const memoized = useMemo(() => ([store, setStore]), [store, setStore]);
    
    
      return (
        <RCTX.Provider value={memoized}>
            <button onClick={() => setStore({ bool: !store.bool })}>
                Switch Bool
            </button>
            <SubComponent />
        </RCTX.Provider>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 2018-12-21
      • 1970-01-01
      • 2019-03-05
      • 2021-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多