You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 10:51:28