NextJS+TypeScript中使用Context时Dispatch类型报错求助
问题
在NextJS + TypeScript项目中使用React Context时,为Context默认值设置useState的setter函数时出现类型错误:Property 'Dispatch' does not exist on type 'typeof import("d:/NextJS/crypto-tracker/node_modules/@types/react/index.d.ts")'
移除Dispatch后,SetStateAction也会报相同错误。
相关代码与配置如下:
Context文件代码
"use client"; import React, { createContext, useEffect, useState, Dispatch } from "react"; export const CryptoContext = createContext({ allCoins: [], currency: { name: "usd", symbol: "$" }, setCurrency: React.Dispatch< React.SetStateAction<{ name: "usd"; symbol: "$" }> >, }); const CryptoContextProvider = ({ children, }: Readonly<{ children: React.ReactNode; }>) => { const [allCoins, setAllCoins] = useState([]); const [currency, setCurrency] = useState({ name: "usd", symbol: "$" }); const fetchAllCoins = async () => { const options = { method: "GET", headers: { accept: "application/json", "x-cg-demo-api-key": "", }, }; fetch( `https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.name}`, options ) .then((res) => res.json()) .then((res) => setAllCoins(res)) .catch((err) => console.error(err)); }; useEffect(() => { fetchAllCoins(); }, [currency]); const contextValue = { allCoins, currency, setCurrency }; return ( <CryptoContext.Provider value={contextValue}> {children} </CryptoContext.Provider> ); }; export default CryptoContextProvider;
package.json配置
{ "name": "crypto-tracker", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev --turbopack", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "next": "15.1.7", "react": "^19.0.0", "react-dom": "^19.0.0" }, "devDependencies": { "@eslint/eslintrc": "^3", "@types/node": "^20", "@types/react": "^19.0.10", "@types/react-dom": "^19", "eslint": "^9", "eslint-config-next": "15.1.7", "postcss": "^8", "tailwindcss": "^3.4.1", "typescript": "^5" } }
tsconfig.json配置
{ "compilerOptions": { "target": "ES2017", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "plugins": [ { "name": "next" } ], "paths": { "@/*": ["./*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] }
已尝试重装react、@types/react、react-dom,切换TypeScript版本至5.7.3,错误仍未解决。
解决方案
1. 修正Context类型与默认值定义
核心问题是:你将类型引用作为createContext的默认值,而非实际运行时值;同时错误地通过React.前缀访问已导入的类型。修改后的代码如下:
"use client"; import React, { createContext, useEffect, useState, Dispatch, SetStateAction } from "react"; // 先定义Context的完整类型 type CryptoContextType = { allCoins: any[]; // 建议替换为具体的硬币类型,比如Coin[] currency: { name: "usd"; symbol: "$" }; setCurrency: Dispatch<SetStateAction<{ name: "usd"; symbol: "$" }>>; }; // 提供合法的默认值(空函数作为setter的兜底实现) export const CryptoContext = createContext<CryptoContextType>({ allCoins: [], currency: { name: "usd", symbol: "$" }, setCurrency: () => {}, // 必须传入实际函数,不能用类型引用 }); // Provider部分代码保持不变 const CryptoContextProvider = ({ children, }: Readonly<{ children: React.ReactNode; }>) => { const [allCoins, setAllCoins] = useState<any[]>([]); const [currency, setCurrency] = useState({ name: "usd", symbol: "$" }); const fetchAllCoins = async () => { const options = { method: "GET", headers: { accept: "application/json", "x-cg-demo-api-key": "", }, }; fetch( `https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.name}`, options ) .then((res) => res.json()) .then((res) => setAllCoins(res)) .catch((err) => console.error(err)); }; useEffect(() => { fetchAllCoins(); }, [currency]); const contextValue = { allCoins, currency, setCurrency }; return ( <CryptoContext.Provider value={contextValue}> {children} </CryptoContext.Provider> ); }; export default CryptoContextProvider;
2. 错误原因解析
- createContext的参数需要运行时可用的值,你之前传入的
React.Dispatch<...>是TypeScript类型,不属于运行时代码,因此报错。 - 你已经从react包导入了
Dispatch和SetStateAction,无需再通过React.前缀访问,这在React 19的类型定义中会导致找不到对应属性。
3. 额外优化建议
为allCoins定义具体类型,提升代码安全性:
// 定义硬币数据的类型 type Coin = { id: string; name: string; symbol: string; current_price: number; image: string; // 根据API返回的字段补充其他属性 }; // 替换useState的泛型 const [allCoins, setAllCoins] = useState<Coin[]>([]); type CryptoContextType = { allCoins: Coin[]; // ...其他属性 };
内容的提问来源于stack exchange,提问作者Swapnodip Chakrabarti
相关产品推荐
相关产品推荐

