Closed subir-sh closed 3 years ago
일단 localStorage.get을 할 이유가 없을 것 같습니다. #531 에서도 말씀드렸듯 다 state에 저장하는 게 좋기 때문에, localStorage에 자주 접근할 필요가 딱히 없습니다!
아무튼 질문에 답변을 드리자면, 비동기 관련 문제는 아닙니다. create-react-app
하고 이 코드 한번 실행해 보시기 바랍니다.
const App = () => {
const [count, setCount] = useState(0);
console.log('a', count);
const handleClick = () => {
console.log('b', count);
setCount(count + 1);
console.log('c', count);
}
return <button onClick={handleClick}>count: {count}</button>;
}
실행해 보시고, 두 번 이상 클릭해보신 다음 콘솔창 캡쳐해서 댓글로 올려보시겠어요?
아 state로 저장하기는 했는데, 새로고침하면 state가 날라가서 다시 토큰 불러오려고 getitem을 쓰고 있습니다.
코드 실행해보니까
a 0
// 한번 클릭
b 0
c 0
a 1
// 두번 클릭
b 1
c 1
a 2
이렇게 나옵니다. b와 c의 값이 같은데, 먼저 쓰여있든 아니든 블럭 안에서 함수가 실행되는 순서가 정해져 있는 것인가요??
아하 그런거였군요 👍
넵 잘 이해하셨습니다. 그러니까 이게 어떻게 되냐면, 렌더가 된다는 건 그 함수 (컴포넌트) 가 실행된다고 생각하시면 돼요
렌더는 우리가 평소 보던 코드처럼
let state = 1;
const func = () => {
console.log(state); // 1
state = state + 1;
console.log(state); // 2
}
이렇게 실행되지 않습니다. 매 렌더마다 필드 및 함수가 새롭게 다시 생성되고, 생성된 아이들은 자기가 생성된 시점의 값들을 이용합니다.
말이 좀 어려운데, 그러니까 무슨 말이냐: 위 코드를 예로 설명하자면
setState
를 이용하면 state가 변경되면서 렌더가 다시 되겠죠?handleClick
에서는 변경된 state가 아닌 기존의 값을 참조합니다.handleClick
이 참조하고 있겠군요때문에 지금과 같이 한 함수 블럭 내에서 (정확히는 하나의 렌더 스코프 안에서) setState를 이용해서 값을 바꾼 다음 바뀐 값을 사용하는 패턴은 불가능합니다! 대신 setState에 넣어준 값이 있을 테니 그 값을 가져다 쓰면 되겠네요 (가령 temp
변수 써서 구현하신 방식처럼요! 그 코드가 정확합니다)
말 나온 김에 좀만 덧붙이자면 setState는 비동기로 작동하기 때문에, 현재 실행 중인 동기 작업이 다 끝난 다음에야 실행됩니다!
https://stackoverflow.com/questions/36085726/why-is-setstate-in-reactjs-async-instead-of-sync
혹시 이 말땜에 더 헷갈리신다면 그냥 무시하시면 됩니다 😅
요약
아마도 비동기/동기 순서 문제인 것 같습니다.
상황
response를 받아서 어떤 함수들의 인자에 값을 넘겨줄 때 문제가 생깁니다.
문제 내용
안녕하세요,
이렇게 하고 token을 하면 제대로 나오는데, localStorage.getItem을 하면 null이 나옵니다. 그런데,
이렇게 하면 잘 작동합니다.
res를 받은 후에는 동기처럼 처리하는 것으로 이해했는데, 그게 아닌가요? 뭔가 더 나은 해결 방법이 있을 것 같아 질문드립니다.