Next.js使用React Context时重复定义数据的优化方案咨询
在Next.js项目中开发navbar组件时,出现了本可避免的代码重复问题:创建并使用React Context的过程中,需要同时在app.tsx和Context.tsx两个文件内定义同一份Array<object>类型的导航数据。
现有代码实现
Context.tsx 代码
在Context.tsx文件中,需要将navbarJSON值传入createContext()函数,因此在该文件内存放了对应的数据对象与类型定义,代码如下:
interface navItem { label: string, itemType: string, position: number, largeDropdown?: Array<any> | null } const navbarJSON: Array<navItem> = [ { label: "About us", itemType: "single", position: 2, largeDropdown: null }, // 其余导航项省略 ] const NavbarContext = createContext(navbarJSON)
app.tsx 代码
在app.tsx文件中,需要存放完全相同的navbarJSON数据和navItem接口,才能将其作为变量传入ContextWrapper组件,代码如下:
interface navItem { label: string, itemType: string, position: number, largeDropdown?: Array<any> | null } const navbarJSON: Array<navItem> = [ { label: "About us", itemType: "single", position: 2, largeDropdown: null }, // 其余导航项省略 ] function MyApp({ Component, pageProps }: AppProps) { return ( <> <ContextWrapper navigation={navbarJSON}> <Component {...pageProps} /> </ContextWrapper> </> ) }
遇到的报错
- 如果将
createContext()的初始值设置为null,代码检查工具在下游navbar组件中无法获取正确的类型,会抛出 Object is possibly 'null' 的警告。 - 尝试为
createContext指定类型并初始化为null时,又收到类型错误:Argument of type 'null' is not assignable to parameter of type 'navItem[]',提示不能将其初始化为null,因为参数要求类型为navItem[]。
2022年6月7日更新
针对@juliomalves提出的疑问:既然已经在Context中设置了默认值,为什么还需要在__app.tsx文件中传入该对象?这里补充之前提问时遗漏的ContextWrapper实现逻辑:
编写的ContextWrapper组件需要接收navigation属性值,再将该属性传入NavbarContext.Provider,如果不传入对应值,Provider会抛出如下错误:
Property 'value' is missing in type '{ children: any; }' but required in type 'ProviderProps<navItem[]>'
ContextWrapper的实现代码如下:
function ContextWrapper({children, navigation} : any) { const [menuItems] = useState(navigation); return ( <NavbarContext.Provider value={menuItems}> {children} </NavbarContext.Provider> ) };
咨询诉求
是否存在更合理的Context定义方式,不需要在两个位置重复定义同一份数据?如有其他疑问会在评论区回复。
内容的提问来源于stack exchange,提问作者IdecEddy
相关产品推荐
相关产品推荐

