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

NextJS(TypeScript)子组件setState类型错误:无法追加状态至数组

解决Next.js + TypeScript中SetStateAction的类型错误问题

嘿,我之前也遇到过完全一样的类型报错!咱们一步步来搞定它。

首先先看你碰到的错误提示:

Type error: Argument of type '(prev: Example[]) => (Example | undefined)[]' is not assignable to parameter of type 'SetStateAction<Example[]>'.

问题根源

这个错误的核心是:你在createExample的onSuccess回调里,把data添加到数组后,得到的数组类型变成了(Example | undefined)[],但你的setItems期望的是纯Example[]类型,所以TypeScript就报错了。

为什么data会可能是undefined?大概率是你的api.example.createExample的返回类型定义里,允许返回Example | undefined——可能是tRPC路由或者Prisma mutation的返回逻辑里,存在成功但不返回对象的情况,或者TypeScript没推断出它一定是有效的Example。

解决方案(按推荐程度排序)

1. 确保data是确定的Example类型(最优解)

先去检查你的API定义(比如tRPC的router或者Prisma的mutation函数),确保createExample成功后必然返回一个有效的Example对象。如果API本身已经保证了这一点,但TypeScript没识别到,你可以临时用类型断言来告诉它:

const { mutate: createExample } = api.example.createExample.useMutation({
  onSuccess: (data) => {
    setItems((prev) => [...prev, data as Example]);
  },
});

当然,最好的方式是完善API的类型定义,让createExample的返回值明确为Example,这样就不需要断言了。

2. 提前过滤掉undefined的情况

如果业务上确实存在data可能为空的场景,那就在更新状态前先做判断:

const { mutate: createExample } = api.example.createExample.useMutation({
  onSuccess: (data) => {
    // 如果data不存在,直接返回,不更新状态
    if (!data) return;
    setItems((prev) => [...prev, data]);
  },
});

这样TypeScript就会知道,进入setItems逻辑时data一定是Example类型,数组类型就匹配了。

3. 调整useState的类型(不推荐)

如果你的业务逻辑允许数组里存在undefined,那可以把主组件的useState类型改成包含undefined的联合类型:

const [items, setItems] = useState<(Example | undefined)[]>([]);

但这显然不符合你要存有效Example的需求,所以只作为极端情况的备选。

额外的小优化

我还注意到你主组件里的列表渲染逻辑可以简化一下:

// 优化后的写法,加了必须的key属性
{items.length > 0 ? (
  <ul>
    {items.map((example) => (
      <li key={example.id}>
        {example.text}{" "}
        <button onClick={() => deleteExample({ id: example.id })}>X</button>
      </li>
    ))}
  </ul>
) : null}

另外,现在Next.js里写组件可以不用FC类型,直接写const Form = ({ setItems }: FormProps) => { ... }就好,代码更清爽。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:16:33