英文:
How can I update an component based on a variable change in React?
问题
所以,我需要基于“currentTodo”来渲染`Todo`组件,比如,如果我的`currentTodo`是2,它应该基于具有`todoId`为2的对象来渲染“Todo”。顺便说一下,我是在`Navbar`组件内部更改`currentTodo`。
```jsx
function App() {
const [todoList, setTodoList] = useState([
{
todoId: 0,
todoName: "个人",
todoTasks: []
},
{
todoId: 1,
todoName: "工作",
todoTasks: []
},
{
todoId: 2,
todoName: "学校",
todoTasks: []
}
])
const[currentTodo, setCurrentTodo] = useState(0)
return (
<>
<Navbar
todo = {todoList}
currentTodo = {currentTodo}
setCurrentTodo = {setCurrentTodo}
/>
{
todoList.map((todo) => {
if(todo.todoId === currentTodo){
return(
<Todo
currentTodo = {currentTodo}
todoList = {todoList}
setTodoList = {setTodoList}
id = {todoList.todoId}
/>
)
}})
}
{console.log(currentTodo)}
{console.log(todoList[currentTodo])}
</>
)
}
但是当我尝试动态更改currentTodo
值时,Todo
组件会简单地消失。如何解决这个问题?
英文:
So, I need to render the Todo
component based on the "currentTodo", like, if my currentTodo
is 2, it should render the "Todo" based on the object that has the todoId
2. By the way, I'm changing the currentTodo
inside the Navbar
component.
function App() {
const [todoList, setTodoList] = useState([
{
todoId: 0,
todoName: "Personal",
todoTasks: []
},
{
todoId: 1,
todoName: "Work",
todoTasks: []
},
{
todoId: 2,
todoName: "College",
todoTasks: []
}
])
const[currentTodo, setCurrentTodo] = useState(0)
return (
<>
<Navbar
todo = {todoList}
currentTodo = {currentTodo}
setCurrentTodo = {setCurrentTodo}
/>
{
todoList.map((todo) => {
if(todo.todoId === currentTodo){
return(
<Todo
currentTodo = {currentTodo}
todoList = {todoList}
setTodoList = {setTodoList}
id = {todoList.todoId}
/>
)
}})
}
{console.log(currentTodo)}
{console.log(todoList[currentTodo])}
</>
)
}
But when I try to change the currentTodo
value dynamically, the Todo
component simply disappears.<br> How can I fix it?
答案1
得分: 1
如Robo的回答中所提到的,最好使用.find
而不是.map
,并检查每个交互。但是,你的解决方案应该可以工作,我认为你可能面临另一个问题。
当你从导航栏动态更新currentTodo
时,如果新值currentTodo
与任何ID都不匹配,那么不会显示Todo
组件,问题可能出在你如何更新它上。
如果你将值设置为一个字符串:
setCurrentTodo("2"); //示例
那么===
不会匹配,除非你将其更改为==
或只是将新值设置为数字:
setCurrentTodo(2); //示例
setCurrentTodo(Number(event.target.value));
英文:
As mentioned in Robo's answer it is better to use .find
rather than .map
and check for each interaction. however, your solution should work and I think you are facing another issue.<br>
when you update currentTodo
dynamically from your navbar, and this new value of currentTodo
does not match any of the ids, then there is no Todo
component displayed, the problem should be how you are updating it.<br> If you set the value to a string
setCurrentTodo("2"); //example
then ===
will not match unless you change it to ==
or just set the new value to a number:
setCurrentTodo(2); //example
setCurrentTodo(Number(event.target.value));
答案2
得分: 0
在你的todo数组上使用.find()
方法来找到匹配的todo。
function App() {
const [todoList, setTodoList] = useState([
// ...
]);
// 我添加了“Id”后缀以清楚表示它是什么
const[currentTodoId, setCurrentTodoId] = useState(0);
const todo = todoList.find(
({ todoId }) => todoId === currentTodoId
);
return (
<>
<Navbar
todo={todoList}
currentTodo={currentTodoId}
setCurrentTodo={setCurrentTodo}
/>
{todo !== undefined && (
<Todo
currentTodo={currentTodoId}
todoList={todoList}
setTodoList={setTodoList}
id={currentTodoId}
/>
)}
</>
);
}
顺便说一下,你的<Todo />
组件的props看起来有点不对。你可能希望它获取一个事件处理程序而不是给它一个setter。
你也可以考虑使用useMemo()
来使用.find()
找到匹配的todo,但除非你有成千上万个todos并且需要频繁重新渲染,否则这是不必要的。
英文:
Use .find()
method on your todo array to find the matching todo.
function App() {
const [todoList, setTodoList] = useState([
// ...
]);
// I added the "Id" suffix to make it clear what it is
const[currentTodoId, setCurrentTodoId] = useState(0);
const todo = todoList.find(
({ todoId }) => todoId === currentTodoId
);
return (
<>
<Navbar
todo = {todoList}
currentTodo = {currentTodoId}
setCurrentTodo = {setCurrentTodo}
/>
{todo !== undefined && (
<Todo
currentTodo = {currentTodoId}
todoList = {todoList}
setTodoList = {setTodoList}
id = {currentTodoId}
/>
)}
</>
);
}
By the way, the props of your <Todo />
component look a bit off. You probably want to make it get an event handler instead of giving it a setter.
You can also consider using useMemo()
for finding the matching todo with .find()
, but it's unnecessary unless you're having thousands of todos and/or you're re-rendering a lot.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论