React函数组件作为useState初始值报children undefined,用React.memo修复的原因?
问题成因
- 核心触发点是React useState的惰性初始化规则
React的useStateHook有专门的惰性初始化设计:如果传入的初始值是普通可执行函数,React会自动调用该函数,将返回值作为state的初始值,用于避免昂贵的初始化计算在每次渲染时重复执行。
你的代码中const [Component, setComponent] = useState(AppLayout[APP_TYPE.WEB])里,未被React.memo包裹的DefaultLayout本身就是普通函数组件,属于可执行的普通函数,因此会被React当作初始化函数直接调用,且调用时不会传入任何props参数。此时DefaultLayout接收的第一个参数props就是undefined,尝试解构{ children, pageProps }自然就抛出了“无法解构undefined的children属性”的错误。 - React.memo生效的原因
React.memo包裹组件后返回的是React.MemoExoticComponent类型的特殊组件对象,不属于普通可执行函数范畴,因此useState不会将它当作初始化函数执行,而是直接把该组件对象作为state的初始值保存。后续你用<Component pageProps={pageProps}>的方式渲染时,才会正常传入props和children,不会触发报错。
推荐修复方案
不建议靠React.memo绕开问题,更合理的修复方式有两种:
- 给useState传入返回组件的惰性初始化函数,明确告诉React初始值是函数返回的组件:
const [Component, setComponent] = useState(() => AppLayout[APP_TYPE.WEB])
- 仅在state中存储布局类型标识,渲染时再匹配对应的组件(更符合React最佳实践):
// state存布局类型 const [layoutType, setLayoutType] = useState(APP_TYPE.WEB) // 渲染时匹配对应组件 const Component = AppLayout[layoutType]
内容的提问来源于stack exchange,提问作者Yeshwanth Kumar
相关产品推荐
相关产品推荐

