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

如何在点击数组元素时使用useState仅修改被点击元素?

问题与代码

你的原始代码如下:

// Using a boolean data type as state
const [layerOne, setLayerOne] = useState(false)

// Looping three elements and I want to modify only the element that I click
{[1, 2, 3].map((o, i) => (
          <div
            key={i}
            id={`opt-${i}`}
            className="option"
            onClick={() => setLayerOne(!layerOne)}
          >
            {layerOne ? <BsEyeSlashFill size={21} /> : <BsEyeFill size={21} />}
            <div className="option__tittle">
              {layerOne ? 'hide' : 'show'} layer
            </div>
          </div>
        ))}

你希望点击列表中的某个元素时,仅修改该元素的状态,而非全部元素一起切换,打算为每个项设置独立的布尔状态,该如何实现?

解决方案

你当前的问题在于用单个布尔值layerOne共享控制所有元素的状态,所以点击任何一个都会触发全局切换。要实现独立控制,需要用数组或对象来存储每个元素的独立状态,以下是两种可行方式:

方式一:用数组存储状态(适合固定长度的列表)

直接用数组对应每个元素的状态,索引和map的下标一一对应:

// 初始化数组,长度和列表元素数量一致,初始值全为false
const [layerStates, setLayerStates] = useState([false, false, false])

{[1, 2, 3].map((o, i) => (
  <div
    key={i}
    id={`opt-${i}`}
    className="option"
    onClick={() => {
      // 复制原数组,避免直接修改state(React要求不可变更新)
      const updatedStates = [...layerStates];
      // 切换当前点击元素对应的状态
      updatedStates[i] = !updatedStates[i];
      setLayerStates(updatedStates);
    }}
  >
    {/* 根据当前索引对应的状态渲染图标和文字 */}
    {layerStates[i] ? <BsEyeSlashFill size={21} /> : <BsEyeFill size={21} />}
    <div className="option__tittle">
      {layerStates[i] ? 'hide' : 'show'} layer
    </div>
  </div>
))}

方式二:用对象存储状态(适合动态长度的列表)

如果你的列表是动态生成的(比如元素数量不固定),用对象存储更灵活,键可以用元素的唯一标识(这里用索引):

// 初始化为空对象,后续动态添加每个元素的状态
const [layerStates, setLayerStates] = useState({})

{[1, 2, 3].map((o, i) => (
  <div
    key={i}
    id={`opt-${i}`}
    className="option"
    onClick={() => {
      // 函数式更新,确保拿到最新的state
      setLayerStates(prevStates => ({
        ...prevStates,
        // 切换当前元素的状态,未初始化时默认是false,!undefined会转为true
        [i]: !prevStates[i]
      }))
    }}
  >
    {/* 用空值合并运算符处理未初始化的状态,默认显示show状态 */}
    {layerStates[i] ?? false ? <BsEyeSlashFill size={21} /> : <BsEyeFill size={21} />}
    <div className="option__tittle">
      {layerStates[i] ?? false ? 'hide' : 'show'} layer
    </div>
  </div>
))}

内容的提问来源于stack exchange,提问作者Aurelio Martín

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:48:29