[React]데이터 자동 불러오기: useEffect와 비동기 함수(async)

정호·2023년 7월 30일

React

목록 보기
21/30

4. 데이터 자동 불러오기: useEffect와 비동기 함수(async)

useEffect는 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정하는 훅이며, 주로 외부 데이터(API)를 가져올 때 사용됨

리액트 컴포넌트 내부에서 비동기 데이터를 다룰 때는 실행 타이밍과 상태 업데이트의 순서를 정확히 제어해야 한다.


useEffect의 구조 분석

단순히 데이터를 가져오는 것을 넘어, 로딩 상태와 에러 처리를 포함한 안정적인 구조를 갖춰야 한다.

useEffect(() => {
  async function fetchPlaces() {
    setIsFetching(true); // 1. 로딩 시작! (사용자에게 "가져오는 중"이라고 알려줌)
    try {
      // 2. http.js 등에 정의된 함수를 실행해서 서버의 데이터를 기다림(await)
      const places = await fetchUserPlaces();
      setUserPlaces(places); // 3. 성공하면 그 데이터를 상태(state)에 저장
    } catch (error) {
      // 4. 네트워크 문제 등이 생기면 에러 상태 저장
      setError({ message: error.message || 'Failed to fetch user places.' });
    }
    setIsFetching(false); // 5. 성공하든 실패하든 로딩은 끝났으니 꺼줌
  }

  fetchPlaces(); // 6. 정의한 비동기 함수를 즉시 실행
}, []); // 7. 의존성 배열: 빈 배열이면 컴포넌트가 처음 나타날 때 "딱 한 번"만 실행

useEffect는 "화면이 뜨자마자 서버에 저장된 내 데이터를 자동으로 불러오는 자동 시작 버튼"과 같다.

왜 useEffect 안에서 async 함수를 따로 만드나요?

리액트의 규칙상 useEffect의 첫 번째 인자인 콜백 함수 자체를 async로 만들 수 없기 때문이다.

  1. 리턴값의 충돌: 리액트는 useEffect의 리턴값으로 컴포넌트가 사라질 때 실행할 '클린업 함수'를 기대한다.

  2. Promise의 문제: async 함수는 항상 Promise를 리턴한다. 즉, 리액트가 기대하는 '함수'가 아닌 '객체'를 주게 되어 충돌이 발생한다.

  3. 해결책: 내부에서 별도의 async 함수를 정의하고 즉시 호출하는 방식을 사용한다.

컴포넌트 생명주기와 데이터 흐름

데이터가 서버에서 넘어오는 과정은 컴포넌트의 생명주기와 밀접하게 연결된다.

❖ 데이터 패칭 프로세스:

  • 탄생 (Mount): 컴포넌트가 화면에 그려지면 useEffect가 실행되어 서버에 요청을 보냄

  • 진행 (Fetching): 데이터가 오는 동안 isFetchingtrue가 되어 화면에 로딩 메시지를 노출함

  • 완료 (Success): 데이터 도착 시 setUserPlaces가 호출되며 리렌더링이 발생하고 실제 내용이 나타남

코드 속의 세심한 처리들

단순한 데이터 호출보다 중요한 것은 예외 상황에 대한 대비이다.

❖ 안전장치 설계:

  • error 상태: 서버가 꺼져 있거나 주소가 잘못된 경우 catch 블록을 통해 사용자에게 에러를 알림

  • 조건부 렌더링: !error일 때만 리스트를 보여주는 등의 처리를 통해 앱이 멈추는 것을 방지함

  • 비어 있는 의존성 배열([])은 사용자가 다른 버튼을 눌러도 데이터를 중복해서 불러오지 않게 막아줌

profile
열심히 기록할 예정🙃

0개의 댓글