ReactJS - useState 更新顶级组件中的值但组件不会重新呈现

ReactJS - useState updates value in top-level component but component doesn't re-render

所以我有一个组件传入了一个 'posts' 变量,它由 useState 管理,在我的 App 组件中我有一些使用该变量的子组件:

function App() {

    const [posts, updatePosts] = useState([
        {
            title: "Cut the Grass",
            description: "Get it done before 4pm",
        },
        {
            title: "Purchase LOTR: DVD box set",
            description: "Extended Edition."
        }
    ])

    return (
        <div>
            <UserBar loggedInFlag = {userIsLoggedIn}/>
            <br /><br /><hr /><br />

            <CreateTodo todoList={posts} updatePosts = { () => updatePosts } />
            <input type="submit" value="test" onClick={() => console.log(posts)}/>
            <TodoList items={posts}/>

        </div>
    )
}
export default App;

我的 CreateTodo 组件中有一个逻辑,可以获取新 post 的字段,将其添加到 posts 数组,并成功更新 posts 变量;我可以使用第二行的“测试”按钮对此进行测试,它始终会向控制台打印出正确的待办事项列表,并且它包含我的新 post。所以这告诉我,<CreateTodo>posts 的更新会很好地冒泡到我的 App 组件。

但是,<TodoList > 组件使用与上面相同的 posts 变量,在更新变量时不会重新呈现。当我更改 IDE 中的某些代码时,该组件仅显示待办事项列表(具有新值),保存,然后页面刷新为新列表。 如何修复我的 useState,以便每当更新 post 值时,它会自动重新呈现 <TodoList > 组件?

作为参考,这是该组件的外观。

export default function TodoList({ items}) {
    
    return (
        <div>
            {items.map( (todo, i) => <Todo {...todo} title={todo.title} description={todo.description} key={'post-' + i} />)}
        </div> 
    )

下面是 CreateTodo 组件的外观:

import React from 'react'

export default function CreateTodo ({todoList, updatePosts}) {
     return (
          <form onSubmit={e => e.preventDefault()} style={{borderStyle:"solid"}}>

             <div>
                 <br/>
                 <label htmlFor="create-title">Title:</label>
                 <br/>
                 <input type="text" id="create-title" />

                 <br/>
                 <label htmlFor="create-title">Description (optional):</label>
                 <br/>
                 <input type="text" id="create-description" />
                 <br/>

                 <br/>
             </div>

             <input type="submit" value="Create" onClick={() => addTodo({todoList, updatePosts})}/>
         </form>   
          )
 }
 

 function addTodo({todoList, updatePosts}){
    let newTodo = {
        title : document.getElementById("create-title").value,
        description : document.getElementById("create-description").value,
        dateCreated : Date.now(),
        completed : false,
        dateCompleted : null
    }

    todoList.push(newTodo);
    updatePosts(todoList);

    document.getElementById("create-title").value = "";
    document.getElementById("create-description").value = "";

    // alert(`"${newTodo.title}" has been added to list`);
 }

您需要在 updatePosts 属性中添加 ()

updatePosts={() => updatePosts()} 或者只是 updatePosts={updatePosts}

首先,您需要将 updatePosts 函数直接传递给您的组件:

<CreateTodo todoList={posts} updatePosts={updatePosts} />

其次,在您的 addTodo 函数中,您直接改变状态对象:

// Don't do this
todoList.push(newTodo);

您需要做的就是使用更新后的列表调用 updatePosts

updatePosts([
  ...todoList,
  newTodo,
]);