setState未更新数组



我正在用reactjs创建一个todo应用程序,我试图在用户单击输入时更新我的todo项目列表。当用户单击时,我可以更改项目,但项目的状态不会更新。我不明白为什么状态没有更新。我认为它与。map()和返回todo对象到新数组有关,但我不太清楚出了什么问题。什么好主意吗?

App.js

import React from 'react'
import TodoItem from './components/TodoItem'
import TodosData from './TodosData'
import './App.scss'
class App extends React.Component {
constructor() {
super()
this.state = {
todoItems: TodosData
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(id) {
this.setState( prevState => {
const updatedTodos = prevState.todoItems.map( todo => {
if (todo.id === id) {
todo.completed = !todo.completed
}
return todo
})
return {
todoItems: updatedTodos
}
})
}
render() {
const todosComponents = this.state.todoItems.map( item => {
return <TodoItem key={item.id} todo={item} handleChange={this.handleChange}/>
})

return (
<div className="TodoList">
{todosComponents}
</div>
)
}
}
export default App;

TodosItem.js

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

Issue

你正在改变状态对象。由于嵌套的对象引用是相同的,React会对任何可能更新的内容进行渲染。换句话说,由于对象引用与之前的渲染相同,React假设没有任何变化。

handleChange(id) {
this.setState( prevState => {
const updatedTodos = prevState.todoItems.map(todo => {
if (todo.id === id) {
todo.completed = !todo.completed // <-- object mutation!!
}
return todo
})
return {
todoItems: updatedTodos
}
})
}
<标题>

解决方案除了浅层复制数组,你还需要浅层复制任何你正在更新的嵌套状态。

handleChange(id) {
this.setState( prevState => {
const updatedTodos = prevState.todoItems.map(todo => {
if (todo.id === id) {
return {
...todo // <-- copy todo
completed: !todo.completed, // <-- update propety
}
}
return todo
})
return {
todoItems: updatedTodos
}
})
}

最新更新