【问题标题】:React hooks updating array is not working反应钩子更新数组不起作用
【发布时间】:2021-12-15 21:57:34
【问题描述】:

我目前正在学习hook,正在写一个todo-list:

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是干什么用的。

【问题讨论】:

    标签: javascript arrays reactjs react-hooks react-state


    【解决方案1】:

    没问题

        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 组件是你的问题。

    【讨论】:

      【解决方案2】:

      问题在于,每次您的组件渲染时,它都会执行completeTaskdeleteTask,因为您使用函数调用 作为道具。您需要传入一个函数 object 或表达式。函数调用不是告诉组件在单击时执行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={() =&gt; deleteFunction(arg)},因为括号和箭头使其成为函数表达式。

      请参阅处理事件:https://reactjs.org/docs/handling-events.html

      【讨论】:

        【解决方案3】:

        正如我所见,您在同一函数中执行console.log(tasks)。 尝试console.log(tasks) 外部函数,您将看到tasks 数组包含您输入的值。

        【讨论】:

          【解决方案4】:

          您的代码运行良好,没有问题。

          以异步方式响应 setState 操作。尝试登录useEffect

          const App = () = => {
              const [tasks, setTasks] = useState([]);
          
              useEffect(() => {
                  console.log(tasks)
              }, [tasks]);
          
              const addTask = () => {
                  const newTask = {...};
                  setTasks([...tasks, newTask]);
              }
          }
          

          useEffect Docs

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-09-27
            • 2021-05-19
            • 1970-01-01
            • 1970-01-01
            • 2020-09-24
            • 2021-04-10
            • 2019-09-15
            • 1970-01-01
            相关资源
            最近更新 更多