React中如何为映射数组内的指定任务字段单独设置编辑模式?
问题
从Firebase获取任务列表并映射渲染多个任务卡片,为每个卡片的字段(如标题、负责人)添加编辑模式。目前用useState维护布尔值editTitle控制编辑态切换,更新Firebase字段的功能已实现,但切换时所有任务的同名字段会同步进入编辑模式,如何实现仅目标任务的对应字段开启编辑?
相关代码片段
const ifEditTitleIsTrue = (element, index) => { return ( <div> <input type="text" defaultValue={element.Title} onChange={(e) => setUpdatedTitle(e.target.value)} /> <button className="exit__editmode-btn btn" onClick={exitEditMode}> X </button> <button className="update__edit-btn btn" id="updateTitle" onClick={(e) => updateField(e, element.id)} > ok </button> </div> ); }; // if editTitle = false (default): const ifEditTitleIsFalse = (element, index) => { return ( <h3 id={index} className="task-title" onDoubleClick={() => setEditTitle(true)} > {element.Title} </h3> ); }; // edit mode for inCharge field const ifEditInChargeIsTrue = (element, index) => { return ( <div> { <GetCollaboratorsForEditMode catchValueInCharge={catchValueInCharge} /> } <button className="exit__editmode-btn btn" onClick={exitEditMode}> X </button> <button className="update__edit-btn btn" id="updateInCharge" onClick={(e) => updateField(e, element.id)} > ok </button> </div> ); };
{tasks[0] && tasks.map((element, index) => ( <div id={element.id} className="task" key={element.id}> {editTitle ? ifEditTitleIsTrue(element, index) : ifEditTitleIsFalse(element, index)}
解决方案
核心问题是单个布尔值editTitle会全局控制所有任务的编辑状态,改成记录当前处于编辑状态的任务ID,就能精准定位单个任务的字段编辑。
步骤1:修改状态定义
把原来的全局布尔状态,改成记录当前编辑任务的ID:
// 初始值设为null,表示没有任务处于编辑状态 const [editingTitleTaskId, setEditingTitleTaskId] = useState(null);
步骤2:更新编辑切换逻辑
- 进入编辑:双击标题时,把当前任务的
element.id存入状态 - 退出编辑:把状态设回
null
修改对应函数:
const ifEditTitleIsFalse = (element, index) => { return ( <h3 className="task-title" // 双击时记录当前任务ID,仅开启该任务的编辑模式 onDoubleClick={() => setEditingTitleTaskId(element.id)} > {element.Title} </h3> ); }; // 退出编辑模式的函数 const exitEditMode = () => { setEditingTitleTaskId(null); };
步骤3:判断单个任务的编辑状态
渲染时不再用全局布尔值,而是判断当前任务ID是否等于状态中记录的ID:
{tasks[0] && tasks.map((element, index) => ( <div id={element.id} className="task" key={element.id}> {/* 仅当前任务ID匹配时,显示编辑框 */} {editingTitleTaskId === element.id ? ifEditTitleIsTrue(element, index) : ifEditTitleIsFalse(element, index)} </div> ))}
步骤4:负责人字段的同理改造
如果要实现负责人字段的独立编辑,需单独维护对应状态:
// 单独维护负责人字段的编辑状态 const [editingInChargeTaskId, setEditingInChargeTaskId] = useState(null); // 负责人字段的非编辑态渲染 const ifEditInChargeIsFalse = (element) => { return ( <p onDoubleClick={() => setEditingInChargeTaskId(element.id)}> {element.InCharge} </p> ); }; // 渲染时判断 {editingInChargeTaskId === element.id ? ifEditInChargeIsTrue(element, index) : ifEditInChargeIsFalse(element)}
最终效果
每个任务的字段编辑状态独立控制,双击某任务的标题/负责人时,只有该任务的对应字段进入编辑模式,其他任务不受影响。
内容的提问来源于stack exchange,提问作者Jonathan Ribak
相关产品推荐
相关产品推荐

