What I Learnd/TIL

TIL - 상태로 data값 관리해서 불러오기 (useState, useEffect, 비동기작업)

키싸 2023. 7. 13. 14:26

Problem


데이터 값을 불러오려는데, 함수 내부 데이터를 가져오기만 하고 반환은 하지 않는 문제

const Details = () => {
  const navigate = useNavigate();

  // ★data 찾기★
  const params = useParams();
  const { id } = params;

  const foundData = async () => {
    const { data } = await api.get("/posts");

    const foundItem = data.find((item) => item.id === parseInt(id));
    console.log("foundItem ->", foundItem);
  };
  console.log("foundData->", foundData);

  useEffect(() => {
    foundData();
  }, []);
 
 {...}
 
export default Details;

 

Solve


데이터값을 상태로 관리해줘야 했다.

// 상태로 foundData 관리
  const [foundData, setFoundData] = useState(null);

  const navigate = useNavigate();
  const params = useParams();
  const { id } = params;

  useEffect(() => {
    const fetchData = async () => {
      const { data } = await api.get("/posts");
      const foundItem = data.find((item) => item.id === parseInt(id));
      if (foundItem) {
        setFoundData(foundItem); // foundData 상태에 값을 설정합니다.
      } else {
        navigate("/");
      }
    };

    fetchData();
  }, [id, navigate]);

  if (!foundData) {
    return <div>Loading...</div>; // 데이터를 아직 불러오지 않았을 때 로딩 상태를 표시함
  }

useState를 사용해서 'foundData' 상태와 'setFoundData'를 정의하고 'useEffect' 훅을 사용하여 데이터 값을 가져온다.
이 때 'foundItem'이 있는 경우 'setFoundData'로 상태 값을 업데이트한다.

 

비동기 작업 설명 추가


: API 요청을 통해 데이터를 불러올 때 일반적으로 비동기 작업을 수행하는데, JavaScript는 이러한 비동기 작업을 수행할 때 해당 작업이 완료될 때까지 다른 작업을 수행하며, 작업이 완료되면 그 결과를 처리할 수 있다.

위 코드에서도 'foundData' 상태가 'null'인 경우에 대한 처리를 처음에는 해주지 않아 다시 오류가 났었지만,
이후 "Loading..."을 표시하는 JSX 반환을 세팅해준 후 문제없이 정상 작동했다.

  if (!foundData) {
    return <div>Loading...</div>; // 데이터를 아직 불러오지 않았을 때 로딩 상태를 표시함
  }

 

Points


  • 상세 페이지의 데이터를 불러올 때 'useEffect' 내에서 비동기 함수인 'fetchData' 사용
  • 이 안에서 API 요청 데이터 불러옴
  • 잘 불러와지면 'foundData'에 설정
  • BUT, 데이터가 아직 로드되기 전에 컴포넌트가 렌더링이 되면 'foundData'는 'null'로 초기화 되어 있으므로, 'null'인 상태에서는 해당 데이터의 속성에 접근할 때 오류가 발생!!!
  • 데이터가 로드되기 전 로딩상태 표시를 추가해줌으로써 데이터가 로드되면 'foundData'가 업데이트되어 실제 데이터를 표시할 수 있게 해준다!