ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • useState 바로 뒤에 console.log 를 했더니 이전 값이 나온다.(혹은 비어있다)
    React/React 2023. 3. 7. 17:12

    📌 useState 바로 뒤에 console.log 를 했더니 이전 값이 나온다.(혹은 비어있다) 라는 문제가 생겼다.

     

    코드를 먼저보자

    import { useEffect, useState } from "react";
    
    function Todolist() {
    
      const [todo, setTodo] = useState<string>("");
    
      const todoHandler = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        const todoData = new FormData(e.currentTarget);
        const newTodo = todoData.get("todo") as string;
        setTodo(newTodo);
        console.log(todo) //비어있는 값이 출력된다.
        e.currentTarget.reset();
    };
    
    useEffect(()=>console.log(todo) , [todo])
    
      return (
        <>
          <div>
            <form onSubmit={todoHandler}>
              <input type="text" name="todo" placeholder="write to do" />
              <button>Add</button>
            </form>
            {todo}
          </div>
        </>
      );
    }
    
    export default Todolist;

    todoHandler 에서 setTodo 를 세팅하고 console.log(todo)를 호출하였는데 

    세팅한 값이 나오지 않고 처음엔 비어있고 그다음부터는 이전 값이 출력된다.

     

    이유는 바로  useState 는 비동기 이기 때문이다. 

    즉 setTodo는 잠시 미뤄두고 console.log 를 먼저 실행해버리기 때문에 이전값이 출력되어 버리는 것이다.

     

    📌그렇다면 setTimeout 을 통해  console.log 를 나중에 실행하면 값이 할당된 상태에서 출력되지 않을까?

    그래서 console.log 대신 아래 코드로 5초뒤에 출력되게 해보았다.

    setTimeout(()=>console.log(todo) , 5000)

    그러나 문제는 여전히 계속되었다. 이유는 다음과 같다.

     

    setTimeout 을 통해 5초 뒤 호출되는 것은 맞으나 호출시점에서 변수의 값을 가져가는 것이 아니다.

    이미 함수가 명령된 상태에서 todo의 값을 가져간 뒤 단순히 5초뒤 실행된것이기 때문이다.

     

    📌 해결방법은 useEffect(()=>console.log(todo) , [todo])

    이미 가장 처음 전체 코드에서도 보았듯

    useEffect 를 통해 todo가 변했을때 console.log 가 실행될 수 있도록 하는 것이 해결책이다.

    댓글

Designed by Tistory.