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

React .map渲染列表时如何仅让点击编辑的项切换编辑状态

问题原因

你当前所有列表项共用了isShow、unShow两个全局布尔状态,只要状态更新,所有map渲染的项都会读取到同一个状态值,自然会全部切换成编辑态,和你点的是哪一项没有关联。

解决方案

核心思路:不要用全局布尔值控制编辑态,改为存储当前处于编辑状态的行ID,每一行渲染时单独判断自身ID是否匹配编辑ID,再决定显示文本还是输入框。

  • 第一步:替换原有状态定义
    删掉原来的isShow、unShow两个布尔状态,新增一个存储编辑行ID的状态:
    // 默认值为null,代表无行处于编辑状态
    const [editingId, setEditingId] = useState(null)
    
  • 第二步:把事件处理函数移到map循环外部(避免每次渲染重复创建函数),修改切换逻辑:
    // 点击编辑/取消按钮的逻辑
    const handleEditToggle = (id) => {
      // 如果当前点击的行已经是编辑态,就退出编辑(设为null),否则把当前行id设为编辑态
      setEditingId(currentId => currentId === id ? null : id)
    }
    
    // 编辑确认逻辑,提交后退出编辑态
    const handleEditConfirm = () => {
      // 这里写你原来的提交保存逻辑
      // ...
      // 保存完成后退出编辑
      setEditingId(null)
    }
    
  • 第三步:修改列表渲染逻辑,每一行单独判断是否为当前编辑项
    注意:列表key建议用数据唯一IDval._id,不要用map遍历的索引key,避免列表顺序变动时出现渲染bug。
    <tbody>
      {carsList.map((val) => {
        // 判断当前行是否处于编辑态
        const isEditing = editingId === val._id
        return (
          <tr key={val._id}>
            <th scope='row'>
              {isEditing ? (
                <input 
                  type="text" 
                  onChange={(event) => {newsetCarsName(event.target.value)}} 
                  defaultValue={val.carsName}
                />
              ) : (
                <p>{val.carsName}</p>
              )}
            </th>
            <th scope='row'>
              {isEditing ? (
                <input 
                  type="text" 
                  onChange={(event) => {newsetModel(event.target.value)}} 
                  defaultValue={val.carsModels}
                />
              ) : (
                <p>{val.carsModels}</p>
              )}
            </th>
            <th scope='row'>
              {isEditing ? (
                <input 
                  type="text" 
                  onChange={(event) => {newsetDate(event.target.value)}}
                  defaultValue={val.carsDate}
                />
              ) : (
                <p>{val.carsDate}</p>
              )}
            </th>
            <th scope='row'>
              {isEditing ? (
                <input 
                  type="text" 
                  onChange={(event) => {newsetNbkm(event.target.value)}} 
                  defaultValue={val.carsNbkm}
                />
              ) : (
                <p>{val.carsNbkm}</p>
              )}
            </th>
            <th scope='row'>
              {isEditing ? (
                <input 
                  type="text" 
                  onChange={(event) => {newsetPrice(event.target.value)}} 
                  defaultValue={val.carsPrice}
                />
              ) : (
                <p>{val.carsPrice}</p>
              )}
            </th>
            <th scope='row'>
              {isEditing ? (
                <input 
                  type="text" 
                  onChange={(event) => {newsetPowch(event.target.value)}}
                  defaultValue={val.carsPowch}
                />
              ) : (
                <p>{val.carsPowch}</p>
              )}
            </th>
            <th scope='row'>
              <button onClick={() => Delete(val._id)}>Delete</button>
            </th>
            <th scope='row'>
              {isEditing && (<button onClick={handleEditConfirm}>Modifier</button>)}
              {!isEditing && (<button onClick={() => handleEditToggle(val._id)}>Edit</button>)}
              {isEditing && (<button onClick={() => handleEditToggle(val._id)}>Annuler</button>)}
            </th>
          </tr>
        )
      })}
    </tbody>
    
补充说明

原来的input用placeholder展示原有值不符合交互逻辑,改成defaultValue直接把原有值填充到输入框里,用户编辑时不需要从头输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:39:30