Next.js中使用Context API从Layout传值到子组件遇undefined问题求助
问题原因
你调用useContext(userContext)的位置不在Context Provider的作用域内,导致获取的值为undefined。
具体来说,你的ComingSoonCarbon组件中,useContext是在<Layout>标签外部执行的,而Context Provider是包裹在Layout组件内部的children区域。当组件执行到const value = useContext(userContext)时,当前组件树还没有进入Provider的覆盖范围,自然无法拿到传递的country值。
解决方案
方案1:拆分组件,将useContext移到Provider作用域内
把需要使用Context值的部分拆成独立组件,放在Layout的包裹范围内:
// ComingSoonCarbon.js import React from 'react' import Layout from '../components/layout' import CarbonContent from './CarbonContent' const ComingSoonCarbon = () => { return ( <Layout> <CarbonContent /> </Layout> ) } export default ComingSoonCarbon // CarbonContent.js import React, { useContext } from 'react' import { userContext } from '../components/layout' const CarbonContent = () => { const value = useContext(userContext) console.log("mamamamia", value) return ( <div className="flex justify-center font-bold mt-80 text-xl text-[rgb(245,132,38,0.93)]"> <h1>{value}</h1> </div> ) } export default CarbonContent
方案2:将children作为函数传递(无需拆分组件)
修改Layout组件,支持将children作为函数执行,这样就能在Provider作用域内调用useContext:
// Layout.js import { useState, createContext } from 'react' import useAPIStore from "../store/store"; import React from 'react'; export const userContext = createContext(); const Layout = ({ children }: Props) => { const [selected, setSelected] = useState(countries[0]); console.log("The country idsz ...........", selected.id) const country = selected.id return ( <> <LayoutContent sidebar={open} countriesWithsrc={countriesWithsrc} selected={selected} lected={setSelected} > <userContext.Provider value={country}> {/* 判断children是否为函数,是则执行 */} {typeof children === 'function' ? children() : children} </userContext.Provider> </LayoutContent> </> ) } export default Layout;
然后修改ComingSoonCarbon组件,把内部内容作为函数返回:
// ComingSoonCarbon.js import React, { useContext } from 'react' import Layout from '../components/layout' import { userContext } from '../components/layout' const ComingSoonCarbon = () => { return ( <Layout> {() => { const value = useContext(userContext) console.log("mamamamia", value) return ( <div className="flex justify-center font-bold mt-80 text-xl text-[rgb(245,132,38,0.93)]"> <h1>{value}</h1> </div> ) }} </Layout> ) } export default ComingSoonCarbon
额外检查点
- 确保
countries[0]存在且具有id属性:如果countries是异步加载的数据,初始渲染时countries可能为空数组,此时countries[0]为undefined,selected.id也会是undefined,导致Provider传递的值无效。可以给Context设置默认值(如createContext(null)),或者在useState中添加空值判断:useState(countries[0] || { id: null })。
内容的提问来源于stack exchange,提问作者Hosea Kibet
相关产品推荐
相关产品推荐

