简体   繁体   English

反应 setState 不更新复选框选中状态

[英]React setState not updating checkbox checked state

I'm following a React beginners tutorial making a todo app as an example.我正在关注 React 初学者教程,以制作待办事项应用程序为例。

in the App.js, there is a handleChange method that will update the state whether the checkbox is checked or not, and passes it into the TodoItem component在 App.js 中,有一个 handleChange 方法会更新状态是否选中复选框,并将其传递给 TodoItem 组件

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            todos: todosData
        }
        this.handleChange = this.handleChange.bind(this)
    }

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

    render() {
        const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item} handleChange={this.handleChange}/>)
        return (
            <div className="todo-list">
                 {todoItems}
            </div>
        )    
    }
}
export default App

TodoItem.js待办事项.js

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

it successfully displays the list and the console log correctly displays the checkbox clicked, however, the checkbox does not change.它成功显示列表,控制台日志正确显示单击的复选框,但是,复选框不会更改。 Can anyone tell me the problem?谁能告诉我问题?

I think you are running into a state mutation problem which is causing some unexpected behavior.我认为您遇到了导致一些意外行为的状态突变问题。 The reason for this is because inside your if statement within map you are not returning your modified array item and you are actually modifying your state array and your new array.这样做的原因是因为在mapif statement ,您没有返回修改后的数组项,而实际上是在修改状态数组和新数组。

How to fix: return your modified array item inside the if statement如何解决:在 if 语句中返回修改后的数组项

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

Or use a one liner with conditional (ternary) operator:或者使用带有条件(三元)运算符的单行:

this.setState(prevState => ({
  ...prevState,
  todos: prevState.todos.map(todo => todo.id === id ? { ...todo, ...{ completed: !todo.completed } } : todo)
}))

Look at this example I created in playground to get a better understanding:看看我在操场上创建的这个例子,以获得更好的理解:

I defined two arrays, one array uses map() without the return and the other array is using map() with the return.我定义了两个数组,一个数组使用map()而不返回,另一个数组使用map()返回。

Our goal is to keep our two arrays exactly the same and using map() to create a new modified array.我们的目标是保持我们的两个数组完全相同,并使用map()创建一个新的修改后的数组。 Look at the log results and notice how our initial array gets modified aswell.查看日志结果并注意我们的初始数组是如何被修改的。 Our second todo item in this array should have a completed value of true but it gets changed to false after our map() which we would want to avoid.我们在这个数组中的第二个待办事项应该有一个completedtrue值,但是在我们想要避免的map()之后它被更改为false By returning our array item in the correct way we avoid this.通过以正确的方式返回我们的数组项,我们可以避免这种情况。

To get a better understanding of what state mutation is and how to avoid check this .为了更好地了解什么是状态突变以及如何避免检查这一点

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM