[React] React의 setState와 비동기 처리

React에서 useState를 사용하여 상태(state)를 관리할 때, 간혹 상태 업데이트가 예상대로 이루어지지 않는 상황을 경험할 수 있습니다. 특히, setState가 비동기적으로 동작하는 점을 이해하는 것이 중요합니다. 이번 글에서는 이와 관련된 문제와 해결 방법에 대해 다루어 보겠습니다.

문제 상황

아래 코드는 useState를 사용하여 상태를 업데이트하고, 업데이트된 상태를 기반으로 API 호출을 시도하는 예제입니다.

const [a, setA] = useState(null); 

const settingA = () => { 
  setA(1);
  callAPI();
}

const callAPI = () => {
  console.log(a);
}

callAPI();

여기서 settingA 함수가 호출되면, 상태 a1로 업데이트되고, callAPI 함수가 호출되어 콘솔에 a의 값을 출력할 것으로 예상할 수 있습니다. 하지만 실제로 콘솔에 찍히는 값은 null입니다. 왜 그럴까요?

원인 분석

setState는 비동기적으로 동작합니다. 즉, setA(1)이 호출되더라도 즉시 상태가 업데이트되지 않으며, 리렌더링 이후에야 새로운 상태 값이 반영됩니다. 따라서 setA를 호출한 직후 callAPI를 호출하면 여전히 이전 상태 값을 참조하게 됩니다.

해결 방법

상태 업데이트 후 특정 작업을 수행하려면 useEffect 훅을 사용하는 것이 좋습니다. 상태 값이 변경될 때마다 그에 따라 필요한 작업을 수행하도록 할 수 있습니다. 다음은 이를 구현한 예제입니다.

import React, { useState, useEffect } from 'react';

const MyComponent = () => {
 const [a, setA] = useState(null);
 const [isSetA, setIsSetA] = useState(false);
 const settingA = () => {
    setA(1);
    setIsSetA(true);
  }
  useEffect(() => {
    if (isSetA) {
      callAPI();
    }
  }, [isSetA]);
  const callAPI = () => {
    console.log(a);
    setIsSetA(false);
  }
  return (
    <div>
      <button onClick={settingA}>Set A and Call API</button>
    </div>
  );
}

export default MyComponent;

개선된 방법

위 코드도 동작하긴 하지만, isSetA라는 추가적인 상태를 사용하지 않고 더 간단하게 해결할 수 있습니다. useEffect를 사용하여 상태 a가 변경될 때마다 callAPI를 호출하도록 합니다.

import React, { useState, useEffect } from 'react';

const MyComponent = () => {
  const [a, setA] = useState(null);
  const settingA = () => {
    setA(1);
  }
  useEffect(() => {
    if (a !== null) {
      callAPI();
    }
  }, [a]);
  const callAPI = () => {
    console.log(a);
  }

  return (
    <div>
      <button onClick={settingA}>Set A and Call API</button>
    </div>
  );
}

export default MyComponent;

이제 상태 a가 변경될 때마다 callAPI가 호출되며, 콘솔에 1이 출력될 것입니다.

마무리

React에서 상태 관리와 비동기 업데이트는 중요한 개념입니다. setState가 비동기적으로 동작함을 이해하고, useEffect를 활용하여 원하는 타이밍에 작업을 수행할 수 있도록 코드를 작성하는 것이 중요합니다. 이 글이 여러분의 개발에 도움이 되었길 바랍니다. 질문이나 더 나은 방법이 있다면 댓글로 공유해주세요!

읽어주셔서 감사합니다.

다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2024년 6월 12일 오후 12:11

댓글 0

    함께 읽은 게시물

    MCP는 기술적으로는 거의 순수하게 Function Calling의 Thin Wrapper에 불과함.


    다만, 현재 대부분의 애플리케이션이 Function Calling을 지원하지 않는 상태라, LLM에 Function Calling을 주입할 수 있는 서버를 쉽게 만들 수 있는 라이브러리를 제공했던 것이 MCP를 확산시키는 데에 크게 기여를 한 것.


    ... 더 보기


    가장 훌륭한 경비절감 방법은 ‘몰입’이다. 가장 훌륭한 생산성 향상 방법도 ‘몰입’이다. 이는 많은 경영학자들이 연구를 통해 증명한 사실이다.

    ... 더 보기

    [백진기 칼럼]그래 한번 미쳐보자?(110편)

    메디칼타임즈

    [백진기 칼럼]그래 한번 미쳐보자?(110편)

    Vibe Coding 매뉴얼

    ... 더 보기

    Vibe Coding 매뉴얼: AI 지원 개발을 위한 템플릿 :: ROBOCO

    roboco.io

     Vibe Coding 매뉴얼: AI 지원 개발을 위한 템플릿 :: ROBOCO

     • 

    저장 19 • 조회 5,386


    [서평]일잘러의 비밀, 챗GPT와 GPTs로 나만의 AI 챗봇 만들기

    ... 더 보기

    사용자가 공유한 콘텐츠

    www.hanbit.co.kr

    사용자가 공유한 콘텐츠

    Modal 을 어떻게 구현하시나요?

    ... 더 보기

    - YouTube

    youtu.be

     - YouTube

     • 

    저장 26 • 조회 2,638