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

React点击map渲染元素切换样式,报setActive不是函数如何解决

问题解决思路

1. 先修复setActive is not a function报错

useState的返回值是数组类型,你错误使用了对象解构语法,导致无法正确拿到状态更新方法,修改如下:

// 错误写法
const { isActive, setActive} = useState(false)
// 正确写法 用数组解构
const [isActive, setActive] = useState(false)

2. 修复点击仅当前元素切换激活类的问题

你当前的isActive是全局布尔值,所有循环渲染的元素共用同一个状态判断,自然会出现点击一个所有元素都切换类的问题。
这里你已经通过dispatch把选中的元素标识存入了AppContext,完全可以直接复用context里的item值做激活判断,不需要额外声明本地状态,最终完整修正代码如下:

const ListItems =  () => {
  const { item: activeItemValue, dispatch } = useContext(AppContext);

  const handler = (item) => {
    dispatch({
      type: 'SET_ITEM',
      payload: item.value,
    });
  };

  return (
    <div className="container">
      <h2 className="smallheader">Please choose one</h2>
      <div className="flex flex-center">
      {ITEMS.map((item) =>
        <div 
          className={activeItemValue === item.value ? 'active-color' : 'card'} 
          data-index={item.value} 
          key={item.id} 
          onClick={() => handler(item)}
        >
        <span
          className="card-header">{item.name}</span>
        <span className="card-description">{item.description}</span>
        </div>
      )}
      </div>
    </div>
  )
};
 
export default ListItems;

实现逻辑说明

  • 用context中存储的选中项value作为激活判断的依据,点击元素时把当前元素的value存入context
  • 循环渲染时判断当前元素的value是否和context中存储的选中值一致,一致就加激活类,否则用默认类
  • 也避免了额外声明本地状态的冗余,逻辑更统一
    如果你不需要把选中值存在全局context,也可以用本地状态实现:
const ListItems =  () => {
  // 存储当前激活元素的value,初始值为null
  const [activeValue, setActiveValue] = useState(null)

  const handler = (item) => {
    // 如果需要点击同一个元素取消激活,可以加判断:setActiveValue(activeValue === item.value ? null : item.value)
    setActiveValue(item.value)
  };

  return (
    <div className="container">
      <h2 className="smallheader">Please choose one</h2>
      <div className="flex flex-center">
      {ITEMS.map((item) =>
        <div 
          className={activeValue === item.value ? 'active-color' : 'card'} 
          key={item.id} 
          onClick={() => handler(item)}
        >
        <span
          className="card-header">{item.name}</span>
        <span className="card-description">{item.description}</span>
        </div>
      )}
      </div>
    </div>
  )
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 00:24:03