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

React版本更新后useReducer钩子要求传入3个参数的问题

解决React.useReducer TypeScript报错:"Expected 3 arguments, but got 2"

我之前也碰到过这个一模一样的坑!在升级到React 16.9.0(包括更高版本)时,用TypeScript写useReducer突然出现这个参数数量不匹配的报错,明明官方文档说第三个参数是可选的,这确实挺让人困惑的。

问题根源

这个问题其实出在**@types/react的类型定义**上,在特定版本的类型文件里,当你显式指定useReducer的泛型参数(也就是<State<D>, Action<D>>这部分)时,类型系统会错误地将第三个初始化函数参数判定为必填项,而不是可选的。这是因为泛型约束的写法导致的,当你手动指定前两个泛型参数后,第三个参数的类型推断逻辑出现了偏差。

解决方案

这里有几个实用的解决办法,按推荐程度排序:

1. 显式传入第三个参数undefined

最简单直接的方式就是给第三个参数传undefined,满足类型检查的要求,同时也符合React的API规范(毕竟它是可选的,传undefined和不传的效果一致):

const [state, dispatch] = React.useReducer<State<D>, Action<D>>(
  reducer,
  { loading: false, data: undefined, error: undefined },
  undefined // 显式传入可选参数
);

2. 让TypeScript自动推断泛型类型

如果你的reducer函数已经有正确的类型定义(比如明确了state和action的类型),可以不用手动指定useReducer的泛型参数,TypeScript会自动推断出正确的类型,这样就不会触发这个报错:

// 确保reducer的类型是:(state: State<D>, action: Action<D>) => State<D>
const [state, dispatch] = React.useReducer(
  reducer,
  { loading: false, data: undefined, error: undefined }
);

3. 调整@types/react版本

如果不想修改代码,可以尝试升级或降级@types/react到同大版本下更稳定的版本。比如16.9.x系列里,@types/react@16.9.50及之后的版本修复了这个类型定义的问题,你可以运行以下命令更新:

npm install @types/react@16.9.50 --save-dev
# 或者用yarn
yarn add @types/react@16.9.50 --dev

4. 使用类型断言(不推荐)

如果你实在不想传undefined,可以用类型断言强制指定返回值的类型,但这种方式可能会掩盖其他潜在的类型问题,所以尽量少用:

const [state, dispatch] = React.useReducer<State<D>, Action<D>>(
  reducer,
  { loading: false, data: undefined, error: undefined }
) as [State<D>, React.Dispatch<Action<D>>];

总结

最稳妥的方式还是前两种:要么显式传undefined,要么让TypeScript自动推断类型。这个问题本质是类型定义的小bug,不是React核心API的问题,所以不用太担心影响功能~

内容的提问来源于stack exchange,提问作者NotsoPr0

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:36:23