亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

復選框在反應 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 關注
  • 162 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號