【问题标题】:ReactJs Context not updated, values always defaultReactJs 上下文未更新,值始终为默认值
【发布时间】:2021-11-23 10:45:02
【问题描述】:
  • 我有父包装组件,我在里面添加了react context
  • 在该包装器组件中,我还有 useEffect() 挂钩,用于从 API 获取一些值,然后将这些值设置为上下文。
  • 在使用上下文的子组件中上下文的值始终是默认值。当我签入浏览器反应工具时,似乎上下文的值已更新,但当我使用 console.log 对其进行测试时,它总是返回默认值。

内部有上下文的父组件:

...
export const CorporateContext = createContext({corporateId: null, corporateRole: null, corporateAdmin: null, corporateSuperAdmin: null});

export const CorporateWrapper = ({ apiBaseUrl, children }) => {
    const [corporateContextDefaults, setCorporateContextDefaults] = 
    useState({corporateId: null, corporateRole: null, corporateAdmin: null, corporateSuperAdmin: null});

    useEffect(() => {
        (async () => {
            try {
                const json = await fetchCorporateUserDetails(apiBaseUrl);

                if (json.success !== true) {
                    console.log(json.message);
                  } else {
                    console.log(json.data) // <-- TESTED RESPONSE FROM API
                    setCorporateContextDefaults(json.data); // <-- UPDATE CONTEXT VALUES HOOK AND PASS IT BELOW TO CONTEXT PROVIDER
                  }

               
                } catch (e) {
                    console.log(e.message);
                }
            })();
    }, []);

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

export default CorporateWrapper;

正在使用该上下文的子组件:

const CorporateSettingsPage: React.FC<CorporateSettingsPageProps> = ({
  apiBaseUrl,
  campusBaseUrl,
  ecomBaseUrl,
}: CorporateSettingsPageProps) => {
  const corporateContext = useContext(CorporateContext);

  console.log('corporate context is:');    //<-- ALWAYS RETURNS DEFAULT VALUES
  console.log(corporateContext);


  useEffect(() => {
    (async () => {
      try {
        const json = await fetchCorporateSettings(apiBaseUrl, 
corporateContext.corporateId);
  ...
    })();
  }, [corporateContext]);

  return (
      <CorporateWrapper apiBaseUrl={apiBaseUrl}> // <--- PARENT COMPONENT WITH CONTEXT INSIDE
        <div>
           ...
           <SomeOtherComponent />   // <-- CONTEXT IS CORRECT HERE AND UPDATED VALUES ARE SHOWN
        </div>
      </CorporateWrapper>
  );

【问题讨论】:

  • 尝试在每次更改时记录corporateContextDefaults 的父组件中添加一个useEffect 挂钩。通过这种方式,我们排除了问题不在状态而是在上下文中。如果它没有记录任何内容或在上次更新中记录了默认值,则问题处于状态
  • 我试过了。第一个 console.log 是默认值,然后第二个是来自 api 的值,非常正确。我更新了我的问题。还有一个子组件在其中具有正确的上下文值,因此上下文在那里可以正常工作。也许我的整个“子组件”实际上并不是一个子组件,因为在该页面内我将页面内容包装在包装器组件中
  • 如果您在非孩子中使用您的上下文,那么您发现了您的问题。由于您的组件不会是您定义的提供者的子组件,因此它永远不会收到您的值
  • 现在,当我在 app.js 文件中添加该包装器并将其从上面的文件中删除时,它工作正常。将所有内容都包含在 app.js 中是正确的地方吗?
  • 上下文可以放在任何地方,重要的是你尊重消费者是组件的孩子这一事实。显然,将每个上下文放入 app.js 中很快就会变得难以维护,因此请始终尝试“这是正确的位置吗?”。也许你会注意到创建另一个组件是必要的

标签: reactjs next.js react-context


【解决方案1】:

尝试做这些事情:

  1. 首先确保状态正确更新。这应该足以调试:
useEffect(()=>{
console.log(corporateContextDefaults);
},[corporateContextDefaults])
  1. 如果状态更新正确,则问题出在您的 Provider->Consumer 关系中。

验证您的消费者是提供组件的子组件。

【讨论】:

  • 是的,就是这样 -> 如果状态正确更新,则问题出在您的 Provider->Consumer 关系中。错误的关系
  • @Denis2310 我只是为将来可能会阅读的未来读者指出一个可能的程序,现在我将在上面回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多