Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 复选框在react js中的todo中不起作用_Javascript_Reactjs_Jsx - Fatal编程技术网

Javascript 复选框在react js中的todo中不起作用

Javascript 复选框在react js中的todo中不起作用,javascript,reactjs,jsx,Javascript,Reactjs,Jsx,我正在使用复选框实现Todo。我在状态中有id、内容、状态属性。 状态有3个状态:支出、完成、删除。todolist有一个复选框。如果状态为挂起,则不应选中复选框。如果状态为“完成”,则应选中复选框。默认情况下,状态为“挂起”。应根据状态选中/取消选中复选框。删除todo时,状态应更新为已删除。现在我对复选框的实现感到惊讶。它不符合要求 App.js: import React from 'react'; import Todo from './Todo'; import AddTodo fro

我正在使用复选框实现Todo。我在状态中有id、内容、状态属性。
状态有3个状态:支出、完成、删除。todolist有一个复选框。如果状态为挂起,则不应选中复选框。如果状态为“完成”,则应选中复选框。默认情况下,状态为“挂起”。应根据状态选中/取消选中复选框。删除todo时,状态应更新为已删除。现在我对复选框的实现感到惊讶。它不符合要求

App.js:

import React from 'react';
import Todo from './Todo';
import AddTodo from './AddTodo';

class App extends React.Component{
  state={
   todos:[
   {id:1,content:'Buy milk1',status:'pending'},
   {id:2, content:'buy carrots1', status: 'pending'},
   {id:3,content:'Buy milk2',status:'done'},
   {id:4, content:'buy carrots2', status: 'deleted'}
  ]
}
onDelete=(id)=>{
 const todo = this.state.todos.find((todoItem => todoItem.id === id))
 todo.status ='deleted';
 this.setState([...this.state.todos]);
}
onChangeCheckbox=(id, checked)=>{ 
 const todo = this.state.todos.find((todoItem => todoItem.id === id))
 if(checked){
  todo.status = 'done'
 }
 else{
  todo.status = 'pending'
 }
 this.setState([...this.state.todos]);
 }
addTodo=(todo)=>{
 todo.id=Math.random();
 todo.status = "pending";
 let todos=[...this.state.todos,todo];
 this.setState({todos});
}
render(){
 return(
  <div>
    <h1>Todo's App</h1>
    
    <AddTodo addTodo={this.addTodo} />
    <Todo todos={this.state.todos} deleteTodo={this.onDelete} onChangeCheckbox= 
    {this.onChangeCheckbox} />
   </div>
  )
 }
}

export default App;
AddTodo.js:

  import React from 'react';

class AddTodo extends React.Component{
  state={
    content:''
  }

 handleChange=(e)=>{
    this.setState({
        content:e.target.value
    });
 }
 handleSubmit=(e)=>{
    e.preventDefault();
    this.props.addTodo(this.state);
    this.setState({
        content:''
    })
  }
 render(){
    return(
        <div>
            <form onSubmit={this.handleSubmit}>
                <input type='text' onChange={this.handleChange} value={this.state.content} 
                 placeholder="Enter todo" />
                <input type="submit" value="Submit"/>
            </form>
        </div>
    );
  }
 }
 export default AddTodo;
Todo.js:

 import React, {useState} from 'react';

 const Todo=({todos,deleteTodo, onChangeCheckbox})=>{
   const [checked, setChecked] = useState(false);

   const handleInputChange =(event,id,status)=>{
    setChecked(status=='pending' ? !checked: checked) 
    onChangeCheckbox(id,!checked);
 }
 const todoList=todos.length ? (

    todos.map(todo=>{
        return(
            <div key={todo.id}>
                {(todo.status === 'pending' || todo.status === 'done' )&& (
                        <div>
                            {/* <input
                                type="checkbox"
                                checked={checked}
                                onChange={(event)=>handleInputChange(event,todo.id)}
                            /> */}
                            <input
                                type="checkbox"
                                checked={todo.status === 'pending' ? checked : !checked}
                                onChange= 
                         {(event)=>handleInputChange(event,todo.id,todo.status)}
                            />
                            <p style={todo.status =='pending'? {color:'red'}: 
                      {color:'green',textDecoration:'line-through'}} >
                                {todo.content}
                            </p>
                            <button onClick={()=>deleteTodo(todo.id)}>Delete</button>
                        </div>
                    )}
            </div>
        )
    })
  ):(
    <p>You have no todos</p>
  );
 return(
    <div>
        {todoList}
    </div>
  )
 }
 export default Todo;
提前谢谢。。请在此处找到codesandbox链接:

对于每个待办事项,您只有一个选中状态。 我建议您将选中状态添加到TODO列表中的每个项目中。 然后您可以找到项目并相应地更改状态

对于每个待办事项,您只有一个选中状态。 我建议您将选中状态添加到TODO列表中的每个项目中。
然后您可以找到项目并相应地更改状态

您的代码有一些问题。最大的问题是onDelete、onChangeCheckbox和addTodo处理程序中的状态突变。这些处理程序也不正确地存储todos数组

使用功能状态更新并将现有状态todo数组映射到新数组,然后复制按id匹配的todo项,这样就不会改变状态对象

random生成浮点数,因此很难与==进行比较。我改为为为每个都添加了一个guid

class App extends React.Component {
  state = {
    todos: [
      { id: uuidV4(), content: "Buy milk1", status: "pending" },
      { id: uuidV4(), content: "buy carrots1", status: "pending" },
      { id: uuidV4(), content: "Buy milk2", status: "done" },
      { id: uuidV4(), content: "buy carrots2", status: "deleted" }
    ]
  };

  onDelete = (id) => {
    this.setState((prevState) => ({
      todos: prevState.todos.map((todo) =>
        todo.id === id
          ? {
              ...todo,
              status: "deleted"
            }
          : todo
      )
    }));
  };

  onChangeCheckbox = (id, checked) => {
    this.setState((prevState) => ({
      todos: prevState.todos.map((todo) =>
        todo.id === id
          ? {
              ...todo,
              status: checked ? "done" : "pending"
            }
          : todo
      )
    }));
  };

  addTodo = (todo) => {
    this.setState((prevState) => ({
      todos: [
        ...prevState.todos,
        {
          ...todo,
          id: uuidV4(),
          status: "pending"
        }
      ]
    }));
  };

  render() {
    return (
      <div>
        <h1>Todo's App</h1>

        <AddTodo addTodo={this.addTodo} />
        <Todo
          todos={this.state.todos}
          deleteTodo={this.onDelete}
          onChangeCheckbox={this.onChangeCheckbox}
        />
      </div>
    );
  }
}

您的代码有一些问题。最大的问题是onDelete、onChangeCheckbox和addTodo处理程序中的状态突变。这些处理程序也不正确地存储todos数组

使用功能状态更新并将现有状态todo数组映射到新数组,然后复制按id匹配的todo项,这样就不会改变状态对象

random生成浮点数,因此很难与==进行比较。我改为为为每个都添加了一个guid

class App extends React.Component {
  state = {
    todos: [
      { id: uuidV4(), content: "Buy milk1", status: "pending" },
      { id: uuidV4(), content: "buy carrots1", status: "pending" },
      { id: uuidV4(), content: "Buy milk2", status: "done" },
      { id: uuidV4(), content: "buy carrots2", status: "deleted" }
    ]
  };

  onDelete = (id) => {
    this.setState((prevState) => ({
      todos: prevState.todos.map((todo) =>
        todo.id === id
          ? {
              ...todo,
              status: "deleted"
            }
          : todo
      )
    }));
  };

  onChangeCheckbox = (id, checked) => {
    this.setState((prevState) => ({
      todos: prevState.todos.map((todo) =>
        todo.id === id
          ? {
              ...todo,
              status: checked ? "done" : "pending"
            }
          : todo
      )
    }));
  };

  addTodo = (todo) => {
    this.setState((prevState) => ({
      todos: [
        ...prevState.todos,
        {
          ...todo,
          id: uuidV4(),
          status: "pending"
        }
      ]
    }));
  };

  render() {
    return (
      <div>
        <h1>Todo's App</h1>

        <AddTodo addTodo={this.addTodo} />
        <Todo
          todos={this.state.todos}
          deleteTodo={this.onDelete}
          onChangeCheckbox={this.onChangeCheckbox}
        />
      </div>
    );
  }
}

这是因为您让选中状态侦听当前组件状态,而不是条目状态。而且它们并不同步。所以你有两个解决方案。首先将状态值作为道具传递给选中的状态,以便在状态值更新时更改状态,我认为这样更昂贵。我还有其他建议,完全没有州政府的意见

 // const [checked, setChecked] = useState(false); remove that, you no longer need it

 const handleInputChange =(event,id,status)=>{ 
   let isChecked = status=='pending' ? true: false;
   onChangeCheckbox(id, isChecked);
 }
同时更新输入检查状态

<input
    type="checkbox"
    checked={todo.status === 'pending' ? false : true}
    onChange= {(event)=>handleInputChange(event,todo.id,todo.status)}
 />

这是因为您让选中状态侦听当前组件状态,而不是条目状态。而且它们并不同步。所以你有两个解决方案。首先将状态值作为道具传递给选中的状态,以便在状态值更新时更改状态,我认为这样更昂贵。我还有其他建议,完全没有州政府的意见

 // const [checked, setChecked] = useState(false); remove that, you no longer need it

 const handleInputChange =(event,id,status)=>{ 
   let isChecked = status=='pending' ? true: false;
   onChangeCheckbox(id, isChecked);
 }
同时更新输入检查状态

<input
    type="checkbox"
    checked={todo.status === 'pending' ? false : true}
    onChange= {(event)=>handleInputChange(event,todo.id,todo.status)}
 />

如果你在一个沙箱中提供你的代码,这将有助于解决你的问题。它没有按照要求工作。调试整个代码库不是我们的工作。你试过什么调试?有错误吗?你能明确地说你的代码的哪一部分不符合规范吗?提供一套复制步骤?我们需要的不仅仅是它不起作用。@Vahid Akhtar:您根本不需要任何额外的检查状态,因为您可以完全从todo状态派生任何检查值。下面提供了工作解决方案。如果您在沙箱中提供代码,这将有助于解决您的问题。它不符合要求。调试整个代码库不是我们的工作。你试过什么调试?有错误吗?你能明确地说你的代码的哪一部分不符合规范吗?提供一套复制步骤?我们需要的不仅仅是它不起作用。@Vahid Akhtar:您根本不需要任何额外的检查状态,因为您可以完全从todo状态派生任何检查值。提供了以下工作解决方案。