【问题标题】:Update React context from child component从子组件更新 React 上下文
【发布时间】:2021-10-05 08:07:25
【问题描述】:

我无法从子组件更新我的上下文对象。这是我用于创建反应上下文的提供程序文件,该组件被包裹在根 app.tsx 文件中的整个应用程序中。

我可以在子组件中获取上下文,但我不知道如何更新它。

const CorporateContext = React.createContext(undefined);

export const useCorporateContext = () => {
    return useContext(CorporateContext);
};

export const CorporateProvider = ({ children }) => {
  const [corporateUserData, setCorporateUserData] = useState(undefined);

  useEffect(() => {
      const localStorageSet = !!localStorage.getItem('corporateDetailsSet');

      if (localStorageSet) {
          setCorporateUserData({corporateId: localStorage.getItem('corporateId'), corporateRole: localStorage.getItem('corporateRole'), corporateAdmin: localStorage.getItem('corporateAdmin'), corporateSuperAdmin: localStorage.getItem('corporateSuperAdmin')});
      } else {
          (async () => {
              try {
                  const json = await 
                  fetchCorporateUserDetails(getClientSideJwtTokenCookie());

                  if (json.success !== true) {
                      console.log('json invalid');
                      return;
                  }

                  setCorporateUserData({corporateId: json.data.corporate_id, corporateRole: json.data.corporate_role, corporateAdmin: json.data.corporate_role == 'Admin', corporateSuperAdmin: json.data.corporate_super_admin});
                  addCorporateDetailsToLocalStorage(corporateUserData);
              } catch (e) {
                  console.log(e.message);
              }
          })();
      }
  }, []);

  return (
      <CorporateContext.Provider value={corporateUserData}>
            {children}
      </CorporateContext.Provider>
  );
};

export default CorporateProvider;

更新:这是我更改的内容,上下文似乎已更新(至少在我签入 chrome devtools 时它看起来已更新)但子组件未重新渲染,一切都保持不变:

我将反应上下文更改为:

const CorporateContext = React.createContext({
    corporateContext: undefined,
    setCorporateContext: (corporateContext) => {}
});

更改了组件中的 useState 钩子:

  const [corporateContext, setCorporateContext] = useState(undefined);

将 setState 作为属性传递给上下文:

        <CorporateContext.Provider value={{corporateContext , setCorporateContext}}>
        {children}
    </CorporateContext.Provider>

【问题讨论】:

    标签: reactjs react-context


    【解决方案1】:

    您也可以将setCorporateUserData 作为第二个值传递给提供程序组件,如下所示:

    //...
    return (
          <CorporateContext.Provider value={{corporateUserData, setCorporateUserData}}>
                {children}
          </CorporateContext.Provider>
      );
    

    然后,您可以随时使用 useContext 挂钩将其解构。

    【讨论】:

    • 我试过了,如果我检查浏览器中的反应工具扩展,上下文会更新,但子组件不会重新渲染,所以基本上没有任何变化
    • 请检查我编辑的答案。我做到了,但子组件没有重新渲染
    • 我认为没有必要更改上下文格式。您是否尝试过在子组件中使用 setCorporateUserData?
    • 我尝试使用它,当我在 devtools 中检查该组件但内容未重新呈现时,上下文发生了变化。可以在该上下文文件中使用 useEffect() 挂钩可能会导致问题吗?
    • 看看你做了什么,我想我在这里找不到任何错误。也许this 会有所帮助?
    【解决方案2】:

    我是如何解决这个问题的:

    问题是我已经克隆了corporateContext 对象并更改了该克隆对象的属性,然后我将它传递给了setCorporateContext() 方法。结果,上下文更新了,但反应没有注意到更改和子组件没有更新。

    let newCorporateContext = corporateContext;
    newCorporateContext.property = newValue;
    setCorporateContext(newCorporateContext);
    

    之后,我使用 javascript 扩展运算符在 setCorporateContext() 方法中更改了corporateContext 的属性。

    setCorporateContext({...corporateContext, property: newValue);
    

    之后,react 注意到钩子的变化,子组件被重新渲染!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-22
      • 2019-03-11
      • 2019-06-19
      • 2019-11-23
      • 2020-08-10
      • 2019-04-29
      • 2021-08-07
      • 1970-01-01
      相关资源
      最近更新 更多