React+TypeScript中Context Provider传value报错:Property 'value'不存在
React+TypeScript Context创建报错:Property 'value' does not exist
我在开发React+TypeScript项目时,尝试用Context共享useState状态,但在value={{ isOpen, setIsOpen }}处遇到以下错误:
Type '{ children: ReactNode; value: { isOpen: boolean; setIsOpen: Dispatch<SetStateAction
>; }; }' is not assignable to type 'IntrinsicAttributes & ChildrenProps & { children?: ReactNode; }'.
Property 'value' does not exist on type 'IntrinsicAttributes & ChildrenProps & { children?: ReactNode; }'.
我的代码如下:
import { PropsWithChildren, createContext, useContext, useState } from 'react'; const MenuContext = createContext<MenuContextType>({ isOpen: false, setIsOpen: () => {}, }); interface MenuContextType { isOpen: boolean; setIsOpen: React.Dispatch<React.SetStateAction<boolean>>; } interface ChildrenProps { children: React.ReactNode; } export function MenuContextProvider({ children, }: PropsWithChildren<ChildrenProps>) { const [isOpen, setIsOpen] = useState(false); return ( <MenuContextProvider value={{ isOpen, setIsOpen }}> {children} </MenuContextProvider> ); } export const useMenuContext = () => { useContext(MenuContext); };
我试过传入'MenuContext'、仅传入'isOpen',以及{ isOpen: isOpen, setIsOpen: setIsOpen }作为value,但都没解决。
问题根源
你犯了两个核心错误:
- Provider组件使用错误:你在
MenuContextProvider的返回值里,错误地用了自己定义的MenuContextProvider组件来包裹内容,但这个自定义组件只接受children属性,没有value属性——正确的做法应该用React Context生成的MenuContext.Provider。 - 类型定义顺序错误:你先创建了
MenuContext,后定义MenuContextType,TypeScript在创建Context时还没识别到这个类型,会导致类型推断异常。
另外还有两个小问题需要修正:
PropsWithChildren已经包含了children属性,不需要额外定义ChildrenProps接口,冗余了。useMenuContext没有返回useContext的结果,调用这个hook拿不到上下文数据。
修正后的完整代码
import { PropsWithChildren, createContext, useContext, useState } from 'react'; // 先定义Context类型,再创建Context interface MenuContextType { isOpen: boolean; setIsOpen: React.Dispatch<React.SetStateAction<boolean>>; } const MenuContext = createContext<MenuContextType>({ isOpen: false, setIsOpen: () => {}, }); // 简化Props定义,直接用PropsWithChildren即可 export function MenuContextProvider({ children, }: PropsWithChildren<{}>) { const [isOpen, setIsOpen] = useState(false); // 使用MenuContext.Provider而非自定义的MenuContextProvider return ( <MenuContext.Provider value={{ isOpen, setIsOpen }}> {children} </MenuContext.Provider> ); } // 让hook返回上下文内容 export const useMenuContext = () => { return useContext(MenuContext); };
关键修正点说明
- 切换正确的Provider:
MenuContext.Provider是React Context自带的组件,它接受value属性来传递上下文数据,这才是你需要用来包裹子组件的元素。 - 调整类型顺序:先定义
MenuContextType,再用它来约束createContext的泛型,确保TypeScript能正确识别上下文的类型。 - 简化Props:
PropsWithChildren<{}>已经包含了children属性,不需要额外定义ChildrenProps,如果不需要其他属性,直接用PropsWithChildren<{}>即可。 - 修复自定义hook:
useMenuContext必须返回useContext(MenuContext)的结果,这样其他组件调用这个hook时才能获取到isOpen和setIsOpen。
内容的提问来源于stack exchange,提问作者ImEmo
相关产品推荐
相关产品推荐

