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

React中removeBook正常,addToShelf报setState不是函数错误

问题分析与解决方案

问题根源

你的addToShelf函数报错的核心原因是:BookDetailShelf组件期望接收三个setState函数,但父组件MyLibrary中的CardGridShelf只传递了当前书架对应的那一个。

看MyLibrary的代码:

  • 渲染「To Read」标签页的CardGridShelf时,只传了setToReadList,没有传setReadingNowList和setHaveReadList;
  • 同理,「Reading Now」和「Have Read」的CardGridShelf也只传递了各自对应的set函数。

这就导致BookDetailShelf中未被传递的那两个set函数是undefined:

  • 如果你在「To Read」的弹窗里执行添加到「Have Read」的操作,setHaveReadList是undefined,调用时就会抛出TypeError;
  • 而removeBook能正常工作,是因为删除操作针对的是当前书架,接口返回的shelfResponse刚好匹配当前书架的id,调用的是已传递的set函数,所以不会触发错误。

修复方案

在MyLibrary的每个CardGridShelf组件中,补充传递所有三个setState函数:

// 「To Read」标签页的CardGridShelf
<CardGridShelf
  books={toReadList}
  shelfId={2}
  setToReadList={setToReadList}
  setReadingNowList={setReadingNowList}
  setHaveReadList={setHaveReadList}
/>

// 「Reading Now」标签页的CardGridShelf
<CardGridShelf
  books={readingNowList}
  shelfId={3}
  setToReadList={setToReadList}
  setReadingNowList={setReadingNowList}
  setHaveReadList={setHaveReadList}
/>

// 「Have Read」标签页的CardGridShelf
<CardGridShelf
  books={haveReadList}
  shelfId={4}
  setToReadList={setToReadList}
  setReadingNowList={setReadingNowList}
  setHaveReadList={setHaveReadList}
/>

这样无论你在哪个书架的弹窗里执行添加操作,对应的set函数都已存在,不会再抛出“不是函数”的错误。

额外优化建议

可以考虑将三个书架的状态合并为一个对象,用单个setState函数管理,这样能减少props传递的复杂度,比如:

const [shelves, setShelves] = useState({
  toRead: [],
  readingNow: [],
  haveRead: []
});

后续更新状态时只需调用setShelves(prev => ({ ...prev, [shelfKey]: updatedList })),也避免了多个set函数传递的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:15:30