useState 동기적 비동기적 사용

김병민·2022년 2월 2일
0

리액트

목록 보기
4/5
post-thumbnail

useState 동기적 비동기적 사용

useState이란

상태를 관리할 수 있게 도와주는 HOOK

상태란?
동적인 값 ==> 변경가능한 값

사용방법

예시

const [state, setState] = React.useState(initialState)
// state은 상태값을 담고있는 변수
// setState 상태를 갱신하는 함수

활용

+1 -1 로직 >>일반적인 활용법

import React from "react";
import "./styles.css";

export default function App() {
  const [syncState, setSyncState] = React.useState(1);
  return (
    <div className="App">
      <h1>Hello Asynchronism and Synchronism</h1>
      <h2>press synchronism buttom !</h2>
      <div>{syncState}</div>
      <div>
        <input
          type="button"
          value="add one"
          onClick={() => {
            setSyncState(syncState + 1);
          }}
        />{" "}
        <input
          type="button"
          value="minus one"
          onClick={() => {
            setSyncState(syncState - 1);
          }}
        />
      </div>

    </div>
  );
}

버튼을 누르면 1이 더하기되거나 마이너스되는 간단한 로직

숫자 1을 5번 더하는 로직 - 동기적 비동기적 실행

그럼 여기서 숫자 1을 5번 더하는 로직을 짜면 어떻게 움직일까 ?

import React from "react";
import "./styles.css";

export default function App() {
  const [syncState, setSyncState] = React.useState(1);
  return (
    <div className="App">
      <h1>Hello Asynchronism and Synchronism</h1>
      <h2>press asynchronism buttom !</h2>
      <div>{syncState}</div>

      <div>
        <input
          type="button"
          value="5 times add in a row. (wrong working) "
          onClick={() => {
            setSyncState(syncState + 1);
            setSyncState(syncState + 1);
            setSyncState(syncState + 1);
            setSyncState(syncState + 1);
            setSyncState(syncState + 1);
          }}
        />{" "}
        <input
          type="button"
          value="5 times minus in a row. (wrong working)"
          onClick={() => {
            setSyncState(syncState - 1);
            setSyncState(syncState - 1);
            setSyncState(syncState - 1);
            setSyncState(syncState - 1);
            setSyncState(syncState - 1);
          }}
        />
      </div>
    </div>
  );
}

상식상으로는 버튼을 눌렀을 때

syncState 은 한번에 5가 더해지거나 5가 빼져야 정상이다

하지만 버튼을 누르면 1만 변경된다.

이유는 useState이 비동기적으로 실행 되기 때문이다.

setSyncState으로 상태를 변경하기 전에 두번째 setSyncState가 실행되기 때문이다.

그럼 어떻게 동기적 실행을 할 수 있을까?

어떻게 연속해서 5번을 실행할 수 있을까? => 동기적 실행 방법

먼저 로직을 봐보자

import React from "react";
import "./styles.css";

export default function App() {
  const [syncState, setSyncState] = React.useState(1);
  return (
    <div className="App">
      <h1>Hello Asynchronism and Synchronism</h1>
      <h2>press asynchronism buttom !</h2>
      <div>{syncState}</div>


      <div>
        <input
          type="button"
          value="5 times add in a row. (right working) "
          onClick={() => {
            setSyncState((prev) => {
              return prev + 1;
            });
            setSyncState((prev) => {
              return prev + 1;
            });
            setSyncState((prev) => {
              return prev + 1;
            });
            setSyncState((prev) => {
              return prev + 1;
            });
            setSyncState((prev) => {
              return prev + 1;
            });
          }}
        />{" "}
        <input
          type="button"
          value="5 times minus in a row. (right working)"
          onClick={() => {
            setSyncState((prev) => {
              return prev - 1;
            });
            setSyncState((prev) => {
              return prev - 1;
            });
            setSyncState((prev) => {
              return prev - 1;
            });
            setSyncState((prev) => {
              return prev - 1;
            });
            setSyncState((prev) => {
              return prev - 1;
            });
          }}
        />
      </div>
    </div>
  );
}

바로 setState에 콜백함수를 넣어주는 것이다.

            setSyncState((prev) => {
              return prev - 1;
            });

으로 prev는 이전값 바꿀 값을 리턴하면 setState은 동기적으로 실행이 된다.

결론

프로젝트를 진행하다보면 useState의 값이 원하는 상태값으로 변하지 않을 때가 종종 생긴다. 이럴 경우 useState의 동기 비동기성을 생각하며 로직을 짜 보자

CodeSandBox

profile
I'm beginner

0개의 댓글