skip to Main Content

I am Passing a function from Parent component to child component and then calling that function in child component to update the state of parent component.

In Parent component:

const [todos, setTodos] = useState([]);
const updateTodoInUiAfterEdit = (updatedTodo, todoIdOfEdited)=>{
        var temp = todos;
        for(var i = 0; i < temp.length; i++){
            if(temp[i].todo_id === todoIdOfEdited){
                temp[i].description = updatedTodo;
                break;
            }
        }
        setTodos(temp);
        console.log(todos);
}

It is logging the updated state here correctly, but UI is not updating as per latest state

3

Answers


  1. The following code works:

    const [todos, setTodos] = useState([]);
    const updateTodoInUiAfterEdit = (updatedTodo, todoIdOfEdited)=>{
            let temp = todos;
            let newTodo = []
            for(var i = 0; i < temp.length; i++){
                if(temp[i].todo_id === todoIdOfEdited){
                    temp[i].description = updatedTodo;
                }
                newTodo.push(temp[i]);
            }
            setTodos(newTodo);
            console.log(todos);
    }
    
    Login or Signup to reply.
  2. setTodos is an asynchronous function, which means that the state updates will not take effect immediately.

    For tackling it you have to update the setTodo by using its previous state as an argument.

    Here’s helping code:

    const updateTodoInUiAfterEdit = (updatedTodo, todoIdOfEdited) => {
      setTodos(prevTodos => {
        const temp = [...prevTodos];
        for (var i = 0; i < temp.length; i++) {
          if (temp[i].todo_id === todoIdOfEdited) {
            temp[i].description = updatedTodo;
            break;
          }
        }
        return temp;
      });
    };
    

    Upvote if it helps.. 🙂

    Login or Signup to reply.
  3. The problem is, you are directly changing the state, which is wrong.

    Do not mutate the state directly

    See the updated code:

    const [todos, setTodos] = useState([]);
    const updateTodoInUiAfterEdit = (updatedTodo, todoIdOfEdited)=>{
            //making a copy of todos up to one depth, if you have more than 
            //one depth, then you have to deep clone it
            const temp = [...todos];
            for(let i = 0; i < temp.length; i++){
                if(temp[i].todo_id === todoIdOfEdited){
                    temp[i].description = updatedTodo;
                    break;
                }
            }
            setTodos(temp);
            console.log(todos);
    }
    

    PS: Use let/const instead of var.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search