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

React开发圣诞礼物清单报setAvailability is not a function错误咨询

问题原因

你报错的直接原因是GiftItem组件中useState用法错误:

  • React的useState返回值是长度为2的数组,第一个元素是状态变量,第二个才是状态修改函数,你现在直接把整个返回值赋值给setAvailability,拿到的是数组而不是函数,自然调用的时候会报not a function的错误。
  • 另外你这里useState的初始值写法也有误,你把props传入的available包裹成了对象{available},和实际需要的布尔值类型不符。
  • 还有一个隐藏问题:你当前的giftList是静态数据,没有把礼物的可用状态提升到上层组件维护的话,就算组件内状态改了,重新渲染的时候还是会用giftList里的初始值,状态不会持久。
解决方案

修复直接报错

先修改GiftItem组件的useState写法,即可解决类型报错:

// GiftItem.js 中原来的错误写法
// const  setAvailability = useState({available})
// 替换为正确写法
const [isAvailable, setIsAvailable] = useState(available)

同时修改传给Book组件的参数:

<Book available={isAvailable} setAvailability={setIsAvailable} />

改完之后点击按钮就可以正常切换礼物的可用状态。

可选优化:状态提升实现状态持久化

如果需要切换分类、刷新页面后礼物的预订状态依然保留,需要把状态提升到上层的ShoppingList组件维护:

  1. 在ShoppingList中把giftList转为响应式状态,新增修改状态的方法:
function ShoppingList() {
  const [activeCategory, setActiveCategory] = useState('')
  // 新增giftData状态,用静态giftList作为初始值
  const [giftData, setGiftData] = useState(giftList)
  // 新增修改礼物可用状态的方法
  const updateGiftAvail = (giftName, status) => {
    setGiftData(prev => prev.map(item => {
      if(item.name === giftName) return {...item, available: status}
      return item
    }))
  }
  // 原有分类逻辑不变
  const categories = giftData.reduce(
    (acc, gift) =>
      acc.includes(gift.category) ? acc : acc.concat(gift.category),
    []
  )
  return (
    <div className='shopping-list'>
      <Categories
        categories={categories}
        setActiveCategory={setActiveCategory}
        activeCategory={activeCategory}
      />
      <ul className='gift-list'>
        {/* 遍历giftData而不是原来的静态giftList */}
        {giftData.map(({image, name, available, lien1, lien2, lien3, price, category}) => (
          !activeCategory || activeCategory === category ? (
            <GiftItem
              image={image}
              name={name}
              available={available}
              lien1={lien1}
              lien2={lien2}
              lien3={lien3}
              price={price}
              key={name}
              {/* 把修改方法传给GiftItem */}
              updateAvail={updateGiftAvail}
            />
          ) : null
        ))}
      </ul>
    </div>
  )
}
  1. GiftItem组件不需要再维护内部状态,直接调用父组件传入的方法即可:
// GiftItem.js 中删除原有的useState代码
function GiftItem({image, name, available, lien1, lien2, lien3, price, category, updateAvail}) {
  return (
    // 原有结构不变
    <Book 
      available={available} 
      setAvailability={(val) => updateAvail(name, val)} 
    />
    // 原有结构不变
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:54:03