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

React使用Context传递State与setState时出现TypeError问题的求助

解决React Context状态更新后的TypeError问题

嘿,我看你在使用React Context传递wishList状态时遇到了一个典型的错误——第一次点击正常,第二次就抛出TypeError: wishList.includes is not a function,咱们来拆解问题根源,然后给出修复方案:

问题出在哪?

你的handleWishClick函数里有两个不符合React状态更新规则的操作:

  1. 用push直接修改原数组并返回长度:
setwishList(wishList.push(id))

Array.push()的返回值是数组更新后的长度(数字),而不是更新后的数组。所以第一次点击后,wishList的状态从数组变成了数字,第二次调用includes时,数字类型自然没有这个方法,直接报错。

  1. 直接修改原状态数组:
wishList.splice(wishList.indexOf(id), 1)

splice是直接修改原数组的方法,React依赖状态的引用变化来触发重新渲染,直接修改原数组可能导致组件不更新,或者出现状态不一致的问题。

正确的修复方案

我们需要用不可变更新的方式来修改数组状态,同时避免直接操作原数组:

const { wishList, setwishList } = useContext(Context);

function handleWishClick(id) {
  if (wishList.includes(id)) {
    // 移除id:用filter创建新数组,排除当前id
    setwishList(prevWishList => prevWishList.filter(item => item !== id));
  } else {
    // 添加id:用扩展运算符创建新数组,追加新id
    setwishList(prevWishList => [...prevWishList, id]);
  }
  // 注意:这里打印的是更新前的状态,因为setState是异步的
  // 如果要打印更新后的状态,可以用useEffect监听wishList变化
}

额外的优化建议

  • 优先使用函数式更新:当新状态依赖于旧状态时,用prevWishList => ...的形式能确保你拿到的是最新的状态值,避免异步更新导致的状态不一致。
  • 避免直接修改原状态:React的状态是只读的,所有状态更新都应该通过setState方法,并且返回新的引用(比如新数组、新对象)。
  • Context默认值优化(可选):如果用TypeScript,可以给Context默认值加上类型提示,避免类型报错:
const Context = createContext<{
  wishList: number[];
  setwishList: React.Dispatch<React.SetStateAction<number[]>>;
}>({
  wishList: [],
  setwishList: () => {},
});

这样修改后,你的状态更新就完全符合React的规则,不会再出现类型错误啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:37:44