-
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 가 실행될 수 있도록 하는 것이 해결책이다.
'React > React' 카테고리의 다른 글
React Outlet 적용하기 (0) 2023.02.26 React 기본 css 제거하기 (0) 2023.02.25 React useParams() 사용법 (0) 2023.02.23 React Router 버전 5 , 6 문제 해결 및 차이점 (react-router-dom) (0) 2023.02.23 useEffect 에서 return 문을 왜 쓰이는걸까? (0) 2023.02.14