如何在React中根据变量更改来更新组件?

huangapple go评论72阅读模式
英文:

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: &quot;Personal&quot;,
      todoTasks: []
    },
    {
      todoId: 1,
      todoName: &quot;Work&quot;,
      todoTasks: []
    },
    {
      todoId: 2,
      todoName: &quot;College&quot;,
      todoTasks: []
    }
  ])

  const[currentTodo, setCurrentTodo] = useState(0)

  return (
    &lt;&gt;
      &lt;Navbar 
        todo = {todoList}
        currentTodo = {currentTodo}
        setCurrentTodo = {setCurrentTodo}
      /&gt;
      {
        todoList.map((todo) =&gt; {
          if(todo.todoId === currentTodo){
            return(
              &lt;Todo 
                currentTodo = {currentTodo}
                todoList = {todoList}
                setTodoList = {setTodoList}
                id = {todoList.todoId}
              /&gt;
            )
          }})
      }
      {console.log(currentTodo)}
      {console.log(todoList[currentTodo])}
      
    &lt;/&gt;
  )
}

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(&quot;2&quot;); //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 &quot;Id&quot; suffix to make it clear what it is
  const[currentTodoId, setCurrentTodoId] = useState(0);

  const todo = todoList.find(
    ({ todoId }) =&gt; todoId === currentTodoId
  );

  return (
    &lt;&gt;
      &lt;Navbar 
        todo = {todoList}
        currentTodo = {currentTodoId}
        setCurrentTodo = {setCurrentTodo}
      /&gt;
      {todo !== undefined &amp;&amp; (
        &lt;Todo
          currentTodo = {currentTodoId}
          todoList = {todoList}
          setTodoList = {setTodoList}
          id = {currentTodoId}
        /&gt;
      )}
    &lt;/&gt;
  );
}

By the way, the props of your &lt;Todo /&gt; 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.

huangapple
  • 本文由 发表于 2023年8月4日 00:59:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830177.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定