javascript useState未更新React待办事项列表应用程序中的DOM

eqzww0vc  于 2023-01-04  发布在  Java
关注(0)|答案(3)|浏览(132)

我正在努力学习React的基础知识,并认为制作一个待办事项列表应用程序将是一个很好的帮助我学习的第一个项目。
我有一个添加todos的基本表单,但是,当点击回车键时,DOM并没有改变。下面是我的app.js代码,我认为这可能是我的错误所在:

import AddTodoForm from './components/AddTodoForm.js';
import TodoList from './components/TodoList.js';
import { dataList } from './components/AddTodoForm.js';
import { useState } from 'react';

function App() {

  const[list, setList] = useState([]);

  function update(){
    setList(dataList);
    console.log(list);
    console.log("update function has run.")
  }

  return (
    <div>

      <AddTodoForm update = {update} />

      <h1>My Todos</h1>
        
      <TodoList todos={list} />    

    </div>
  );
}

export default App;

下面是TodoList.js的代码,这是有人要求的:

import Todo from './Todo';

function TodoList(props) {
    return (
        <ul>
            {props.todos.map((todo) => (
                <Todo
                key = {todo.id}
                id= {todo.id}
                text= {todo.text}
                />
            ))}
        </ul>
    )
}

export default TodoList;

下面是AddTodoForm.js:

import { useRef, useState } from 'react';

var idCounter = 1;

export const dataList = [];

function AddTodoForm(props){

    const titleInputRef = useRef();

    function submitHandler(event){
        event.preventDefault();

        const enteredTitle= titleInputRef.current.value;

        const todoData = {
            text: enteredTitle,
            id: idCounter,
        }

        idCounter++;

        console.log(todoData);
        dataList.push(todoData);

       
        
    }

    return (
        <div className="card">
            <h2>Add New Todos</h2>

            <form onSubmit={(event) => {submitHandler(event); }}>
                <div>
                    <label htmlFor="text">New Todo: </label>
                    <input type="text" required id="text" ref={titleInputRef}></input>
                </div> <br />

                <div>
                    <button className="btn" onClick = {props.update}>Add Todo</button>
                </div>
            </form>

        </div>
    )
}

export default AddTodoForm;

我已经检查了日志,更新功能正在运行。另外,如果我对代码做了轻微的更改,我输入的todos将出现在屏幕上,但我不确定为什么当更新功能运行时DOM没有更改。
这是我在这里的第一篇文章,所以我不确定我的代码要包含多少。如果你需要我的其他组件的代码,请询问。
提前感谢:)

bq3bfh9z

bq3bfh9z1#

调用dataList.push(todoData)不会改变dataList本身,只会改变它的内容,而且React不会检查内容来更新DOM。您可以使用Spread syntax来拥有一个全新的dataList
你甚至可以去掉dataList,使用给useState的空数组,稍微修改一下update函数,它应该可以工作了:

import AddTodoForm from "./components/AddTodoForm.js";
import TodoList from "./components/TodoList.js";
import { useState } from "react";

function App() {
  const [list, setList] = useState([]);

  function update(text) {
    // this is for learning; consider using a proper id in real world
    setList([...list, { text: text, id: list.length + 1 }]);
  }

  return (
    <div>
      <AddTodoForm update={update} />
      <h1>My Todos</h1>
      <TodoList todos={list} />
    </div>
  );
}

export default App;
import { useRef } from "react";

function AddTodoForm(props) {
  const titleInputRef = useRef();

  function submitHandler(event) {
    event.preventDefault();
    props.update(titleInputRef.current.value);
  }

  return (
    <div className="card">
      <h2>Add New Todos</h2>

      <form onSubmit={submitHandler}>
        <div>
          <label htmlFor="text">New Todo: </label>
          <input type="text" required id="text" ref={titleInputRef}></input>
        </div>
        <br />
        <div>
          <button className="btn">Add Todo</button>
        </div>
      </form>
    </div>
  );
}

export default AddTodoForm;
sr4lhrrt

sr4lhrrt2#

在App.js中,我删除了update函数,并将listsetList作为 prop 发送给AddTodoForm组件。

import AddTodoForm from './components/AddTodoForm.js';
import TodoList from './components/TodoList.js';
import { useState } from 'react';

function App() {

  const[list, setList] = useState([]);

  return (
    <div>

      <AddTodoForm setList = {setList} list = {list}/>

      <h1>My Todos</h1>
        
      <TodoList todos={list} />    

    </div>
  );
}

export default App;

./components/AddTodoForm.js中,将此代码段添加到AddTodoForm函数中。

const update = ()=>{
    props.setList(datalist);
    console.log(props.list);
    console.log("The update function has run.")
}

希望这能帮上忙。

5t7ly7z5

5t7ly7z53#

我将发表我的观点来帮助你了解React。在你上面的代码中,你不能呈现更新的状态(列表)来反映TodoList组件。
在hook中,useEffect代替了类组件思想的2个组件生命周期,我的意思是,你应该用更新的状态(列表)来反映useEffect,useEffect类似于componentDidMount和componentDidUpdate,如下所示:

enter code here
   useEfect(()=>{
      setList(dataList);
      console.log(list);
      console.log("update function has run.")
   },[list])

相关问题