【发布时间】: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