React任务复选框交互代码逻辑解析求助
代码逻辑逐行解析:Todo任务勾选/取消勾选的位置调整逻辑
下面我们一步步拆解这段代码的执行流程,重点解释你疑惑的「取消勾选倒数第二个任务会移到开头」的逻辑:
1. 复制并更新任务的勾选状态
const updatedTasks = tasks.map((task, i) => i === index ? { ...task, checked: !task.checked } : task );
这一步通过map遍历原任务数组,仅对点击的目标任务(索引为index的项)做状态翻转:如果原任务是勾选状态,就改成未勾选;反之则改成勾选。其他任务保持原样,最终得到状态更新后的新数组,此时任务位置还未调整。
2. 将目标任务移到数组末尾
updatedTasks.push(updatedTasks.splice(index, 1)[0]);
这里是关键的位置调整第一步:
splice(index, 1)会从updatedTasks中移除索引为index的目标任务,splice返回被移除元素组成的数组,所以[0]用于取出这个目标任务。- 再通过
push把这个目标任务添加到数组的末尾。
到这一步,不管是勾选还是取消勾选操作,目标任务都会被先移到数组最后。
3. 根据任务状态决定是否移到开头
if (!updatedTasks[updatedTasks.length - 1].checked) { updatedTasks.unshift(updatedTasks.pop()); }
这是你疑惑的核心逻辑:
- 首先判断当前数组最后一个元素(也就是刚移过来的目标任务)的
checked状态是否为false(即取消了勾选)。 - 如果满足条件,就用
pop()把最后一个元素(目标任务)移除,再通过unshift()把它添加到数组的开头。
针对「取消勾选倒数第二个已完成任务」的场景举例
假设原任务数组是这样(已完成任务checked: true):
tasks = [ { text: "任务1", checked: false }, // 未完成 { text: "任务2", checked: true }, // 已完成 { text: "任务3", checked: true }, // 已完成,倒数第二个(你点击的目标) { text: "任务4", checked: true } // 已完成,最后一个 ];
执行流程如下:
map之后,目标任务(任务3)的checked被翻转为false,数组变为:
[ { text: "任务1", checked: false }, { text: "任务2", checked: true }, { text: "任务3", checked: false }, { text: "任务4", checked: true } ];
splice+push操作后,任务3被移到数组末尾:
[ { text: "任务1", checked: false }, { text: "任务2", checked: true }, { text: "任务4", checked: true }, { text: "任务3", checked: false } ];
- 检测到最后一个元素(任务3)的
checked为false,执行pop+unshift,任务3被移到数组开头:
[ { text: "任务3", checked: false }, { text: "任务1", checked: false }, { text: "任务2", checked: true }, { text: "任务4", checked: true } ];
而勾选任务的场景中,目标任务的checked会被设为true,第三步的if条件不满足,所以任务会留在数组末尾,符合你的预期。
内容的提问来源于stack exchange,提问作者Nixy
相关产品推荐
相关产品推荐

