ReactJs 上下文未更新,值始终为默认值
Posted
技术标签:
【中文标题】ReactJs 上下文未更新,值始终为默认值【英文标题】:ReactJs Context not updated, values always default 【发布时间】: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 中很快就会变得难以维护,因此请始终尝试“这是正确的位置吗?”。也许你会注意到创建另一个组件是必要的
【参考方案1】:
尝试做这些事情:
-
首先确保状态正确更新。这应该足以调试:
useEffect(()=>
console.log(corporateContextDefaults);
,[corporateContextDefaults])
-
如果状态更新正确,则问题出在您的 Provider->Consumer 关系中。
验证您的消费者是提供组件的子组件。
【讨论】:
是的,就是这样 -> 如果状态正确更新,则问题出在您的 Provider->Consumer 关系中。错误的关系 @Denis2310 我只是为将来可能会阅读的未来读者指出一个可能的程序,现在我将在上面回答以上是关于ReactJs 上下文未更新,值始终为默认值的主要内容,如果未能解决你的问题,请参考以下文章
java-int类型:int默认为0导致更新操作未赋值的情况下将值更新为0
从 DropdownItems 中选择值后,DropdownButton 值未更新。如何使用 selectedValue 更新默认值?
如何将 fetch() 函数的结果传递给 React 上下文值,而不是我为钩子设置的默认值?