ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] setState 비동기
    React 2020. 9. 30. 14:23

    안녕하세요. 지난번에 이어 setState에 대해서 알아보겠습니다.

     

    setState를 알아보기 앞서 먼저 비동기 처리의 이해부터 시작하겠습니다.

    javaScript에서 다른 언어와의 큰 차이는 비동기 처리라 할 수 있습니다.

     

    예를들어 func(), func2() 함수를 들어 설명하겠습니다.

    const func = () =>{ setTimeout(()=> { console.log('hello world') } , 1000) };
    
    const func2 = () => { console.log('hi') };
    
    func();
    func2();

    console.log로 콘솔창에 띄울 경우

    • hello world
    • hi

    가 뜰 것으로 이해하지만 직접 띄워본 결과

    이런식으로 hi가 먼저 출력 된 뒤 hello world가 출력되는 것을 알 수 있습니다.

    (setTimeout비동기 콜백함수로 두번째 인자로 시간을 받게 되는데 단위는 ms입니다.)

     

    이런식으로 비동기 함수는 코드를 위에서 아래로 동기적인 처리를 하는 것이 아니라

    다음코드를 먼저 실행하고 해당하는 시간에 맞춰 비동기적으로 코드를 실행하는 것입니다.

     

    setState는 비동기 처리이다!

    (React hooks의 예시)

    const [userStatus, setUserStatus] = useState(true);
    
    const toggleUser = () => {
    	setUserStatus(!userStatus);
    	console.log(userStatus);
    };
    

    만약 이런식으로 userStatus를 console.log로 확인을 해 본다면 console창에는

    userStatus 가 true로 찍혀 있을 것이다.

     

    비동기 함수이기 때문에 console.log가 먼저 실행되고 그 후에 비동기를 처리하는 곳에서 userStatus의

    상태가 바뀐다.

     

    만약 위의 함수를 자식 Component로 줬다면 어떻게 될까?

    <Header userStatus={userStatus} toggleUser={toggleUser} />

    부모 컴포넌트인 ChattingScreen.js 에서 Header 컴포넌트에 toggleUser함수를 넘겨줬다 치자,

    자식에게 state를 전달 해줄 때는 <Header 이름={ 넘겨주고자하는 state } /> 이런식으로 넘겨주면 된다. 

     

    Header.js 파일에는 넘겨 받은 이름을 비구조화 할당으로 { } 안에 넣어주면 자식에서도 부모의 state를

    활용 할 수 있게 된다.

    const Header = ({ userStatus, toggleUser }) => {
    
        const handleUserState = () =>{
        	toggleUser();
        	console.log(userStatus);
        }
    
        return (
          <>
              <button onClick={handleUserState} />
          </>
        );

    하지만 여기서 handleUserState함수를 불렀다 생각할 때, handleUserState는  부모의 toggleUser()를

    호출하게 될 것이고, 이는 부모의 state를 바꾸는 비동기함수인 setUserState()가 작동하게 된다.

    여기서 handleUserState안의 console.log()를하게 된다면 역시나 값이 바뀌지 않은 상태로

    전달 되므로 setUserState와 조건문을 만약에 쓰게 된다면 잘 작동하지 않을 확률이 높다.

     

    따라서 setUserStatus와 status가 들어가는 문장을 되도록이면 섞어 쓰지 않는게 좋을듯하다.

     

    안 좋은 해결방법

    useEffect()

    useEffect(()=>{ 
       if(userStatus){
          원하는 동작
       }
       else{}
    }, [userStatus])

    이런식으로 userStatus가 바뀔 때 userEffect를 불러오므로 활용이 가능하지만 추천하지 않는바이다.

     

    React 에선 왜 state들을 비동기 처리를 할까?

    React에서는 state값이 바뀌면서 re-rendering을 하게 된다. 결국 re-rendering을 하기 위해서는

    setState가 꼭 필요하다.

     

    비동기 처리의 이유는 불필요한 랜더링 횟수를 줄이기 위함이다.

    state의 상태가 바뀔 때마다 리랜더링이 된다면, 불필요한 랜더링 횟수가 늘어난다.

    setState()의 비동기 처리로 인해 한 번에 state를 바꿔줌으로써, 랜더링 횟수를 줄인다.

     

     

    'React' 카테고리의 다른 글

    [React] push, concat, ...(스프레드 연산자) 차이  (0) 2020.09.28

    댓글

Designed by Tistory.