简体   繁体   English

检查复选框在 React 中不起作用

[英]Checking the checkbox is not working in React

This is a simple TO-DO app in react in which App.js takes data from TodosData.js and the list is shown with the component TodoItem.js .这是一个简单的 TO-DO 应用程序,其中App.js TodosData.js数据,列表与组件TodoItem.js Now the checkboxes and data can be viewed when rendered.现在可以在渲染时查看复选框和数据。 But when I click on the checkbox it doesn't work.但是当我点击复选框时它不起作用。 I tried console logging handleChange function which seems to work.我尝试了控制台日志记录handleChange function 这似乎有效。 It seems like there maybe problems inside the handleChange function which I can't figure out.似乎handleChange function 内部可能存在我无法弄清楚的问题。

I am following a freecodecamp tutorial on YT and I also checked it several times but can't find the problem here.我正在关注 YT 上的 freecodecamp 教程,我也检查了几次,但在这里找不到问题。

App.js code: App.js代码:

import React from 'react';
import TodoItem from './TodoItem'
import todosData from './todosData'

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

  handleChange(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(itemEach => <TodoItem key = {itemEach.id} itemEach = {itemEach}
      handleChange = {this.handleChange} />)
    return (
      <div className = "todo-list">
        {todoItems}
      </div>
    )
  }
}

export default App;

TodoItem.js code: TodoItem.js代码:

import React from 'react';

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

export default TodoItem

TodosData.js code: TodosData.js代码:

const todosData = [
  {
    id: 1,
    text: "Take out the trash",
    completed: true
  },
  {
    id: 2,
    text: "Grocery shopping",
    completed: false
  },
  {
    id: 3,
    text: "Clearn gecko tank",
    completed: false
  },
  {
    id: 4,
    text: "Mow lawn",
    completed: true
  },
  {
    id: 5,
    text: "Catch up on Arrested Development",
    completed: false
  }
]

export default todosData

Is there a better way to implement this?有没有更好的方法来实现这一点? This way of doing checkbox seems quite complicated for a beginner like myself.对于像我这样的初学者来说,这种做复选框的方式似乎相当复杂。 Also how can I improve this code?另外我该如何改进这段代码?

You are mutating the state in your handleChange function.您正在修改您的 handleChange function 中的handleChange Hence it gets the prevState twice.因此它两次获得prevState Once for the original previous state, next for the update that you make inside the handleChange .一次用于原始的先前 state,接下来用于您在handleChange中进行的更新。

You can probably lose the reference, by spreading the todo from state like this.通过像这样从 state 传播todo ,您可能会丢失参考。

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

Here's a working codesandbox这是一个有效的代码框

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

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