我是react和javascript领域的新手,我正尝试创建一个todo应用程序来学习,到目前为止,除2件事(删除和if完成功能)外,其他所有功能都可以正常工作。我要实现的目标是使onClick按钮将完成的状态从false更改为true,然后将直通传递给特定的待办事项。之后,我将有3个不同的计数器来显示待办事项的总数,已完成和未完成的数量。代码如下:
class App extends Component {
constructor() {
super();
this.state = {
text: '',
notes: [
{todo: "test", completed: true},
{todo: "test2", completed: false}
]
}
}
handleChange = (e) => {
this.setState({ text: e.target.value })
}
handleSubmit = (e) => {
e.preventDefault();
if(!this.state.text.length) { return }
const newTodo = {
todo: this.state.text,
completed: false
}
const notes = this.state.notes
notes.push(newTodo)
this.setState({
text: '',
notes: notes
})
}
handleClick = (index) => {
const notes = this.state.notes
notes[index].completed = !notes[index].completed
this.setState({ notes })
}
handleDelete = (index) => {
const notes = this.state.notes
notes.splice(index, 1)
this.setState({ notes })
}
render() {
let notes = this.state.notes.map((todo, index) => {
return <Todo key={index} note={todo}
deleteTodo={this.handleDelete} handleClick={this.handleClick}/>
});
return (
<div className="App">
<div className="notes-wrapper">
<Header />
<Form
handleSubmit={this.handleSubmit}
handleChange={this.handleChange}
text={this.state.text}
/>
{notes}
<Footer notesLength={this.state.notes.length} />
</div>
</div>
);
}
}
如果我将obj的数组更改为一个简单的数组,例如array = [1,2,3],则可以执行array.splice(index,1)并运行良好,但是在这种情况下,索引存在问题我明白。删除功能正在工作,但正在删除错误的元素,而不是单击的元素,并且如果我这样做notes [1] .completed =!notes [1] .completed也正在工作,但在两个按钮上都起作用,它将仅更改第一个按钮项目。我不知道对于初学者来说是否很复杂。谢谢!
const Todo = (props) => {
return (
<div className="todo-wrapper">
<li style={{textDecoration: props.note.completed ?
'line-through' : 'none'}}>
<button className="btn btn-remove"
onClick={props.deleteTodo}>Remove</button>
{props.note.todo}
<button className="btn btn-status"
onClick={props.handleClick}>{props.note.completed ?
"Undo" : "Done"}</button>
</li>
</div>
);
答案 0 :(得分:2)
您需要注意两件事,
首先:您没有将索引传递给Todo组件的handleDelete和handleClick函数。
第二:您不应更改原始状态。就像对待它一成不变一样
handleClick = (index) => {
const notes = [...this.state.notes] // create a copy
notes[index].completed = !notes[index].completed
this.setState({ notes })
}
handleDelete = (index) => {
this.setState(prevState => ({ notes: [...prevState.notes.slice(0, index), ...prevState.notes.slice(index) }))
}
render() {
let notes = this.state.notes.map((todo, index) => {
return <Todo key={index} note={todo} index={index}
deleteTodo={this.handleDelete} handleClick={this.handleClick}/>
});
return (
<div className="App">
<div className="notes-wrapper">
<Header />
<Form
handleSubmit={this.handleSubmit}
handleChange={this.handleChange}
text={this.state.text}
/>
{notes}
<Footer notesLength={this.state.notes.length} />
</div>
</div>
);
}
您的Todo组件将具有
<button className="btn btn-remove" onClick={() => props.deleteTodo(props.index)}>Remove</button>
类似
<button className="btn btn-status" onClick={() => props.handleClick(props.index)}>{props.note.completed ? "Undo" : "Done" }</button>