此代码适用于内置react的简单待办事项应用程序。今天,我试图将我的选项1代码重构为类似选项2的内容,但惊讶地发现它破坏了我的removeTask功能。在故障排除期间,我还尝试了选项3,其结果相同。我正在努力找出原因;对我来说,选项2和3与选项1看起来几乎一样,只是比较干净。实施选项2或3时,我没有收到任何错误,但是单击removeTask现在会删除所有先前的任务。这三个之间有什么区别?
问题代码:
//Option 1 (working)
removeTask = (event, index) => {
event.stopPropagation();
const removedTaskArray = [...this.state.tasksarray];
removedTaskArray.splice(index, 1);
this.setState({ tasksarray: removedTaskArray });
};
//Option 2 (broken)
removeTask = (event, index) => {
event.stopPropagation();
const removedTaskArray = [...this.state.tasksarray].splice(index, 1);
this.setState({ tasksarray: removedTaskArray });
};
//Option 3 (broken)
removeTask = (event, index) => {
event.stopPropagation();
const copyOfTasksArray = [...this.state.tasksarray]
const removedTaskArray = copyOfTasksArray.splice(index, 1);
this.setState({ tasksarray: removedTaskArray });
};
完整(有效)代码:
import React, { Component } from 'react';
import './App.css';
/* InputTaskForm renders a form, and returns the input to our storeTask method. */
const InputTaskForm = ({ formValidation }) => {
return (
<form name="charlie" onSubmit={formValidation}>
<input name="userinput" type="text" placeholder="Task..." />
<button type="submit">Submit</button>
</form>
);
}
const DisplayTasks = ({ tasks, removeTask, strikeTask }) => {
return (
<div id="orderedList">
<ol>
{tasks.map((task, index) => (
<li onClick={() => strikeTask(index)} key={index} >
{task.strike ? <strike>{task.title}</strike> : task.title}
<button id="removeButton" onClick={event => removeTask(event, index)} >Remove</button>
</li>
))}
</ol>
</div>
);
};
class App extends Component {
state = {
userinput: '',
tasksarray: [],
}
/* ============================================== #FUNCTIONS ==============================================
=========================================================================================================== */
formValidation = event => { // event prop passed from InputTaskForm component
event.preventDefault(); // prevent form from auto-refreshing on submit
const userInput = event.target.userinput.value // userInput stored
const userInputIsBlank = userInput.trim().length < 1 // trim (remove) prefixed and affixed spaces, then check length
userInputIsBlank
? alert(`Error: invalid submission`)
: this.storeTask(userInput);
};
storeTask = userInput => { // userInput passed from formValidation function
this.setState({
userinput: userInput,
tasksarray: [...this.state.tasksarray, { title: userInput, strike: false } ] //create a copy of tasks array then add a new object into the array filled out with user input
});
document.forms["charlie"].reset();
};
//Option 1 (working)
removeTask = (event, index) => {
event.stopPropagation();
const removedTaskArray = [...this.state.tasksarray];
removedTaskArray.splice(index, 1);
this.setState({ tasksarray: removedTaskArray });
};
strikeTask = index => { // index prop passed from DisplayTasks component
const { tasksarray } = this.state
const selected = tasksarray[index];
this.setState({
tasksarray: [ // change tasksarray state to: [prior slice, change, after slice]
...tasksarray.slice(0, index), // slice off (copies) of array elements prior to index element
Object.assign(selected, {strike: !selected.strike}), // invert the selected line's strike value
...tasksarray.slice(index + 1) // slice off (copies) of array elements after index element
]
});
};
componentDidUpdate() {
console.log(this.state.tasksarray); // debugging :)
};
/* =============================================== #RENDER ================================================
=========================================================================================================== */
render() {
const { tasksarray } = this.state
const { formValidation, storeTask, removeTask, strikeTask } = this
return (
<div>
<InputTaskForm
task={storeTask}
formValidation={formValidation} />
<DisplayTasks
tasks={tasksarray}
removeTask={removeTask}
strikeTask={strikeTask} />
</div>
);
};
};
/* ================================================ #EXPORT ===============================================
=========================================================================================================== */
export default App;
答案 0 :(得分:1)
一切都归结为了解Array##splice的作用,实际上它返回一个包含已删除项目的数组。这是一个小例子:
const a = [1, 2, 3, 4, 5].splice(3, 1); // same as a = [4]
const b = [1, 2, 3, 4, 5];
const c = b.splice(3, 1); // same as b = [1, 2, 3, 5] and c = [4]
答案 1 :(得分:1)
Return value的接合点是
包含删除的元素的数组。如果只有一个元素是 移除后,将返回一个元素的数组。如果没有元素 删除后,将返回一个空数组。
因此,在您的2 nd 和3 rd 方法中,您将放置已删除的元素数组
因此您只需将代码更改为
removeTask = (event, index) => {
event.stopPropagation();
const removedTaskArray = [...this.state.tasksarray]
removedTaskArray.splice(index, 1);
this.setState({ tasksarray: removedTaskArray });
};