为了账号安全,请及时绑定邮箱和手机立即绑定

复选框在反应 js 中的待办事项中不起作用

复选框在反应 js 中的待办事项中不起作用

繁花如伊 2023-05-19 14:40:30
我正在使用复选框实现 Todo。我在该州有一个 id、content、status 属性。Status 有 3 种状态(pending、done、deleted)。待办事项列表有一个复选框。如果状态为待定,则不应选中复选框。如果状态为完成,则应选中复选框。默认情况下,状态为待定。应根据状态选中/取消选中复选框。在删除待办事项时,状态应更新为已删除。现在我对复选框的实现感到震惊。它没有按照要求工作。应用程序.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;
查看完整描述

3 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

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


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


Math.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>

    );

  }

}

也不需要存储任何checked状态,Todo.js因为检查状态很容易从您的todo.status财产中派生出来。如果状态为“完成”,则选中该框。


todos您可以(应该)首先通过过滤器运行您的数组以删除已删除的状态待办事项。


const Todo = ({ todos, deleteTodo, onChangeCheckbox }) => {

  const todoList = todos.length ? (

    todos

      .filter(({ status }) => status !== "deleted")

      .map((todo) => {

        return (

          <div key={todo.id}>

            <div>

              <input

                type="checkbox"

                checked={todo.status === "done"}

                onChange={(event) =>

                  onChangeCheckbox(todo.id, event.target.checked)

                }

              />

              <p

                style={

                  todo.status === "pending"

                    ? { color: "red" }

                    : { color: "green", textDecoration: "line-through" }

                }

              >

                {todo.content}

              </p>

              <button onClick={() => deleteTodo(todo.id)}>Delete</button>

            </div>

            <hr />

          </div>

        );

      })

  ) : (

    <p>You have no todos</p>

  );

  return <div>{todoList}</div>;

};


查看完整回答
反对 回复 2023-05-19
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

checked对于每个项目,您只有一个状态todo。我建议您为列表checked中的每个项目添加状态todos。然后你可以找到项目并相应地改变状态



查看完整回答
反对 回复 2023-05-19
?
慕工程0101907

TA贡献1887条经验 获得超5个赞

发生这种情况是因为您让选中状态监听current component state而不是项目状态。而且它们不同步。所以你有两个解决方案。首先将状态值作为道具传递给已检查状态,以便在状态值更新时让状态发生变化,我认为它更昂贵。我有其他完全没有状态的建议。


 // 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)}

 />

https://codesandbox.io/s/competent-hugle-jn22o?file=/src/Todo.js


查看完整回答
反对 回复 2023-05-19
  • 3 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信