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,
]);
所以我有一个组件传入了一个 '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,
]);