React/React
useState 바로 뒤에 console.log 를 했더니 이전 값이 나온다.(혹은 비어있다)
onurmind38
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 가 실행될 수 있도록 하는 것이 해결책이다.