react.js事件处理程序没有返回更新的数据



我是react.js的新手。我正在youtube上学习react.js的视频。我在简单的事件处理工作,并在一些问题卡住。当用户在复选框上执行onclick功能时,我想选中/取消选中复选框。但不知何故,返回的数组没有更新,复选框也不可操作。我将我的代码粘贴到下面:

App.js

import React from 'react'
import Header from './components/Header'
import Todolist from './components/Todolist'
import todosData from './data/todosData'
class App extends React.Component {
constructor(){
super()
this.state = {
todos: todosData
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(id){
this.setState(prevState => {
console.log(prevState.todos)
const updatedTodos = prevState.todos.map(todo => {
if(todo.id === id){
todo.completed = !todo.completed
}
return todo
})
console.log(updatedTodos)
return{
todos : updatedTodos
}
})
}
render(){
const todoItems = this.state.todos.map(item => <Todolist key={item.id} item={item} handleChange={this.handleChange} />)
return (
<div>
<Header />
{todoItems}
</div>
)
}
}
export default App;

TodoList.js

import React from 'react'
function Todolist(props){
return(
<div className='todo-item'>
<input type='checkbox'
checked={props.item.completed} 
onChange={() => props.handleChange(props.item.id)} 
/>
<span>{props.item.text}</span>
</div>
)
}
export default Todolist

您试图在这一行改变数组的原始项/对象!

todo.completed = !todo.completed

您可以尝试使用Object.assign或使用spread创建一个新对象。两种方式都可以,但传播方式更可取。

使用Object.assign

handleChange(id) {
this.setState((prevState) => {
const updatedTodos = prevState.todos.map((todo) => {
// Object.assign creates a new object!
const changedTodo = Object.assign({}, todo, {
completed: todo.id === id ? !todo.completed : todo.completed
});
return changedTodo;
});
return {
todos: updatedTodos
};
});
}

使用扩展...

handleChange(id) {
this.setState((prevState) => {
const updatedTodos = prevState.todos.map((todo) => {
const changedTodo = {
...todo,
completed: todo.id === id ? !todo.completed : todo.completed
};
return changedTodo;
});
return {
todos: updatedTodos
};
});
}

如前所述,setState在严格模式下运行两次。使用相同的输入调用状态更新器函数两次。这应该是好的,并产生相同的输出。但这里的问题是您重用了todo对象,而不是创建一个新对象。这反过来又导致completed标志被翻转两次。

你可以修改你的updatater函数,每次创建一个新的todo对象:

this.setState(prevState => {
const updatedTodos = prevState.todos.map(todo => {
if (todo.id === id) {
return {
...todo,
completed: !todo.completed,
};
}
return todo;
});
return {
todos: updatedTodos,
};
});

最新更新