[React] useEffect 내에서 Data Fetch를 한다면?

Dongmin Lee·2023년 3월 3일

React

목록 보기
5/11

💿 이 글의 목적

부모 컴포넌트로부터 받은 props를 자식의 jsx문에 직접 넣어주려고 하는데

이런 에러가 출력되었다.
실제로 로그를 찍어봐도 null이 출력된다.
뭐지?
뭐긴 뭐야 기본기 부족이지

💿 이해에 필요한 지식

💾 setState()의 호출 시점

setState는 렌더링 이전에 호출된다.

💾 useEffect()의 호출 시점

useEffect는 렌더링이 끝난 이후 호출된다.

💿 실행 프로세스

import React, { useState, useEffect } from 'react';
import './styles.css';

const App = () => {
  const [usersInfo, setUsersInfo] = useState({});

  useEffect(() => {
    fetch('/mock.json')
      .then((res) => res.json())
      .then((data) => setUsersInfo(data));
  }, []);

  return (
    <div className="app">
      <h1>렌더링 연습 문제!</h1>
      <ul>
        {usersInfo.users.map((user) => {
          return <li key={user.id}>{user.username}</li>;
        })}
      </ul>
    </div>
  );
};

export default App;

컴포넌트가 처음 마운트될 때, useState가 호출되면서 빈 객체가 초기값으로 들어가고,
render가 될때 jsx문에 사용되는 state값에는 빈 객체가 들어가게 된다.
그리고 나서 렌더링이 끝난 후에야 useEffect가 호출되면서 state 값에 fetch로 가져온 데이터가 꽂힌다.
따라서 초기 렌더링 시 map의 객체는 usersInfo.users가 아니라 null이 들어가면서 TypeError가 발생한다.

💿 해결책

아래와 같이 && 연산자를 통해서 map 메소드가 호출되는 부분은 state값이 제대로 들어온 후 조건부로 렌더링이 되게 코드를 짜면 된다

import React, { useState, useEffect } from 'react';
import './styles.css';

const App = () => {
  const [usersInfo, setUsersInfo] = useState({});

  useEffect(() => {
    fetch('/mock.json')
      .then((res) => res.json())
      .then((data) => setUsersInfo(data));
  }, []);

  return (
    <div className="app">
      <h1>렌더링 연습 문제!</h1>
      <ul>
        {usersInfo.user && usersInfo.users.map((user) => {
          return <li key={user.id}>{user.username}</li>;
        })}
      </ul>
    </div>
  );
};

export default App;

💿 Reference

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
위코드 내부 문서

profile
어제보다 성장하기

0개의 댓글