skip to Main Content

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.
How can I fix it?

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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.

    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.
    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));
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search