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

React修改Set类型state后组件未触发重渲染问题排查

问题原因

React 触发重渲染的前提是检测到 state 引用发生变化,内部对 state 做浅比较判断是否需要更新。
当前代码存在两个违反状态不可变原则的问题:

  • let newSet = activeItems 仅拷贝了原 Set 的引用,没有创建新的 Set 实例,后续调用add()/delete()都是直接修改原始 state 对象
  • setActiveItems 最终传回的还是和原 state 指向同一块内存的 Set 对象,React 浅比较判定 state 未发生变化,直接跳过重渲染流程,只有组件重新挂载时才会读取最新的 state 值展示。
修复方法

更新状态时基于原 state 创建全新的 Set 实例,在新实例上做增删操作,保证传回 setState 的是新的引用:

export const InterestsPupup: React.FC = ({interests, title, buttonText}) => {
  const [activeItems, setActiveItems] = useState(new Set())

  const clickOnItemHandler = (item: string) => {
    setActiveItems(prev => {
      // 基于原有Set值创建新实例,生成全新引用
      const newSet = new Set(prev)
      newSet.has(item) ? newSet.delete(item) : newSet.add(item)
      return newSet
    })
  }

  return (
        <div className={styles.Container__main}>
            {interests.map((item , index) => {
              return (
                <div
                  key={index}
                  className={activeItems.has(item) ? clsx(styles.item, styles.item_active) : styles.item}
                  onClick={() => clickOnItemHandler(item)}
                >{item}</div>
              )
            })}
        </div>
  );
};

注意:所有引用类型(Object、Array、Map、Set)作为 state 存储时,都必须遵守不可变更新规则,不能直接修改原对象,要在新的副本上做修改后再传给 setState,否则会出现状态更新但不重渲染的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 23:27:29