簡體   English   中英

反應鈎子更新數組不起作用

[英]React hooks updating array is not working

我目前正在學習鈎子,我正在寫一個待辦事項列表:

import './App.css';
import React, {useState} from 'react';
import Item from './components/Item';
function App() {
  const [tasks, setTasks] = useState([]);

  const addTask = (e) => {
    if(e.key === 'Enter'){
      let newTask = {content: e.target.value, completed: false};
      console.log(newTask);
      setTasks(prevTask => {
        return ([...prevTask, newTask]);
      });  
      console.log(tasks);
    }
  }

  const completeTask = (e) =>{
    let newTask = tasks.slice();
    newTask[e].completed = !tasks[e].completed;
    setTasks(newTask);
  }

  const deleteTask = (e) => {
    let newTask = tasks.slice();
    newTask.splice(e);
    setTasks(newTask);
  }

  return (
    <>
      <header className="todo-app__header">
        <h1 className="todo-app__title">todos</h1>
      </header>
      <section className="todo-app__main">
        <input className="todo-app__input" placeholder="What needs to be done?" onKeyDown={addTask}/>
        <ul className="todo-app__list" id="todo-list">
          {tasks.map(item => <Item num = {tasks.indexOf(item)} text={item.content} completed = {item.completed} 
          onClick = {completeTask(tasks.indexOf(item))} delete = {deleteTask(tasks.indexOf(item))}/>)}
        </ul>
      </section>
    </>
  );
}

export default App;

但是,添加任務不起作用!! 打印的 newTask 很好,但它沒有推入任務數組。 任務還是空的。

有什么問題? 另外,另一個問題:它與useeffect相關嗎? 我不知道useeffect是做什么用的。

問題是每次您的組件渲染時,它都會執行completeTaskdeleteTask ,因為您使用函數調用作為道具。 您需要傳入一個函數對象或表達式。 不是告訴組件在單擊時執行completeTask ,函數調用只是在組件呈現后立即執行它。

問題在於您的代碼的這一部分:

<ul className="todo-app__list" id="todo-list">
    {tasks.map(item => <Item num = {tasks.indexOf(item)} text={item.content} completed = {item.completed} 
    onClick = {completeTask(tasks.indexOf(item))} delete = {deleteTask(tasks.indexOf(item))}/>)}
 </ul>

以下幾行:

delete = {deleteTask(tasks.indexOf(item))}
onClick = {completeTask(tasks.indexOf(item))}

應改為:

delete = {() => deleteTask(tasks.indexOf(item))}
onClick = {() => completeTask(tasks.indexOf(item))}

在普通 HTML 中,它看起來像delete="deleteFunction()" ,但在 React 中,它應該是delete={deleteFunction} ,因為在它之后寫一個帶括號的函數是一個函數調用,而不是一個函數表達式 如果需要傳入參數,可以將參數作為組件的 prop 傳入,或者將行更改為delete={() => deleteFunction(arg)} ,因為括號和箭頭使其成為函數表達。

請參閱處理事件: https : //reactjs.org/docs/handling-events.html

您的代碼運行良好,沒有問題。

異步反應setState動作。 嘗試將其記錄在useEffect

const App = () = => {
    const [tasks, setTasks] = useState([]);

    useEffect(() => {
        console.log(tasks)
    }, [tasks]);

    const addTask = () => {
        const newTask = {...};
        setTasks([...tasks, newTask]);
    }
}

使用效果文檔

正如我所看到的,您在同一個函數中執行console.log(tasks) 在函數外部嘗試console.log(tasks) ,您將看到帶有您輸入的值的tasks數組。

沒有問題

    import React, {useState} from 'react';
function Add() {
    const [tasks, setTasks] = useState([]);
    const addTask = (e) => {
        if(e.key === 'Enter'){
            let newTask = {content: e.target.value, completed: false};
            console.log(newTask);
            setTasks(prevTask => {
               return ([...prevTask, newTask])
            });
            console.log(tasks);
        }
    }

    const completeTask = (e) =>{
        let newTask = tasks.slice();
        newTask[e].completed = !tasks[e].completed;
        setTasks(newTask);
    }

    const deleteTask = (e) => {
        let newTask = tasks.slice();
        newTask.splice(e);
        setTasks(newTask);
    }

    return (
        <>
            <header className="todo-app__header">
                <h1 className="todo-app__title">todos</h1>
            </header>
            <section className="todo-app__main">
                <input className="todo-app__input" placeholder="What needs to be done?" onKeyDown={addTask}/>
                <ul className="todo-app__list" id="todo-list">
                    {tasks.map((item)=> <li>{item.content}</li>)}
                </ul>
            </section>
        </>
    );
}

export default Add;

它運行良好,這意味着您的 Item 組件是您的問題。

嘗試改變:

 setTasks(prevTask => { return ([...prevTask, newTask]); });

setTasks(prevTask => [...prevTask, newTask]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM