[Tistory] 센스있는 비동기 useState

원글 페이지 : 바로가기

업무를 진행하던와중 useState를 사용하여 값을 변경하자마자 그 값으로 API요청을 보내야했던 상황이 있었다. 그러나, “useState는 비동기적인 동작으로 리랜더링이 되어야 처리를 요청한 값이 반영이 된다.” 라는 개념은 알고 있었기에 왜안되는지 까지는 파악하여 진행을하…는도중 끊임 없이 머리속에서 물음표가 떠다녔다. (마치된것 같아 송민호) 그래..안되는거 알겠어…근데왜? useState는 어떻게 동작이되길래 안되는건데 그리고 왜바로 반영이안되는건데 왜 아무튼 이러한 개인적인 궁금증을 풀기위한 글이므로 틀린 지식은 언제든 지적웰컴입니다. 퀴즈🚨 해당 글을 읽기전 하단의 코드가 어떻게 동작될까? 실제로 기술면접에 들어갔을때도 질문으로 받았던 내용입니다. import { useState } from “react”;

export default fnction Example() {
const [val,setVal] = useState(0);

const plus = () => {
setVal(val + 1);
setVal(val + 1);
setVal(val + 1);
};

return (

{val}


);
}; val +1 해당동작이 세번이니까 +3이지 쉽네 ㅋ 네 아닙니다. 동작시켜보시면 해당 val는 1씩 증가하는걸 확인할 수 있습니다. ( •᷄⌓•᷅ ) ꖶዞ¿? val + 1이 세번인데 왜. 우선 이유는 useState 정확히는 setState가 비동기적으로 동작하기 때문입니다. 🤔 setState가 비동기적으로 동작하는 이유 하나의 페이지에는 수많은 상태값이 존재하고, 이 상태가 바뀔때마다 Rerender가 된다면? 성능에 많은 문제가 생길 것입니다. 이 때문에 리액트는 성능 향상을 위해 setState가 연속 호출이 된다면 *배치 처리하여 한번에 랜더링 하도록 했습니다. *배치처리 state의 업데이트 작업을 모아 한번에 처리하는 방식을 Batching 이라고 합니다. ✅ 해결방법 => useState를 동기적으로 처리할 수 있는 방법 그럼 위의 코드에서 버튼 한번으로 +3이 될 수 있는 방법은 두가지가 있습니다. useEffect 사용 setState의 인자로 함수를 집어 넣는 것 setState의 인자로 함수를 집어넣기 import { useState } from “react”;

export default fnction Example() {
const [val,setVal] = useState(0);

const plus = () => {
setVal((val) => val + 1);
setVal((val) => val + 1);
setVal((val) => val + 1);
};

return (

{val}


);
}; 이렇게 코드를 수정해주면 원하는대로 버튼을 누르면 +3으로 올라가는 것을 알 수 있다. 그러나, 여기서 또한번 드는 궁금증은setState는 값을 어떻게 변화시키길래 애가 비동기적으로 작동해! 라는 궁금증이였다. 🧱setState 함수의 상태 변화 과정 우선 위의 코드를 다시가지고 와보자면 import { useState } from “react”;

export default fnction Example() {
const [val,setVal] = useState(0);

const plus = () => {
setVal((val) => val + 1);
setVal((val) => val + 1);
setVal((val) => val + 1);
};

return (

{val}


);
}; const [val,setVal] = useState(0) 해당 부분을 보면 useState를 호출하여 반환값을 구조분해할당으로 추출하여 변수에 저장하는 과정을 거칩니다. 이 개념을 가지고 react 모듈을 뜯어보도록 하겠습니다. 이는 react 모듈 코드인데 이걸 보면 useState 밖에 _value 라는 전역 변수가 존재합니다. 우리가 useState를 통해 값을 관리하는 게 바로 전역 변수인 _value 입니다. 흔히 const [ val , setVal ] = useState(0); 이라는 코드 가 있을때 setVal가 값을 받아서 val로 넘겨주는 군. 이라고 생각하시겠지만 이는 잘못된 생각입니다. setState는 App함수에 선언된 state가 아닌, 자신의 위치에서 접근할 수 있는 _value를 변경합니다. ( 클로저 개념입니다 ) ⚡️ 웹이 로딩되고 Example 함수가 호출 Example은 인수로 0을 전달하면서 useState를 호출합니다. useState는 실행될때마다 initialValue를 전달받지만 _value가 undefined인경우만 _value에 초기값을 할당하기에 최초 호출에만 초기값을 _value에 할당하고, 이후에는 초기값이 사용되지 않습니다. 이후 _value와 그 값을 재할당하는 setState 함수를 배열에 담아 반환합니다. ⚡️ 초기값 저장 후 리렌더링 발생 다시 인수 0 을 useState에 전달하여 호출 이미 _value에는 undefined가 아닌 다른 값이 할당되었기에 초기값 할당문을 실행하지 않습니다. 이후 useState가 현재 시점의 _value , setState를 반환합니다. (_valuse는 1) 두번째 실행된 함수 내부에서 useState가 반환값을 구조분해할당으로 추출하여 변수에 할당. 즉, setState함수는 자신과 함께 반환된 값을 변경시키는 것이 아닌. 다음 useState가 반환할 _value 모듈을 변경시기고, 컴포넌트를 리랜더링시키는 역할을 합니다. 마지막으로 변경된 값은 useState가 가져옵니다. 출처 https://velog.io/@jjunyjjuny/React-useState%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91%ED%95%A0%EA%B9%8C#-setstate-%ED%95%A8%EC%88%98%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%83%81%ED%83%9C%EB%A5%BC-%EB%B3%80%EA%B2%BD%EC%8B%9C%ED%82%A4%EB%82%98 https://velog.io/@alstnsrl98/useState%EB%8A%94-%EB%8F%99%EA%B8%B0-%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%8F%99%EA%B8%B0%EC%A0%81-%EC%B2%98%EB%A6%AC#%EA%B7%B8%EB%9F%BC-usestate%EB%A5%BC-%EB%8F%99%EA%B8%B0%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%B2%98%EB%A6%AC%ED%95%98%EB%A0%A4%EB%A9%B4

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다