본문 바로가기
리액트(React)

리액트로 뉴스뷰어 만들어 보기(2)

by 즐거운코딩 2023. 6. 6.
반응형

뉴스 API 데이터를 연동해보겠습니다.

컴포넌트가 보이는 시점에 API를 요청하면되는데 이때 useEffect를 사용하여 컴포넌트가 렌더링되는 시점에 API를 요청합니다.

여기서 주의해야할 점은 useEffect에 등록하는 함수에 async를 붙이면 안됩니다. useEffect에서 반환해야 한느 값은 뒷정리 함수이기 때문입니다. 따라서 useEffect 내부에서 async/await 를 사용하려면 함수 내부에 async 키워드가 붙은 다른 함수를 만들어 사용합니다.

API 요청이 대기 중인지 판별하기 위해 추가로 loading 이라는 상태도 관리하겠습니다. loagding 중일때는 true, 끝나면 false 로 변경합니다.

import styled from 'styled-components';
import NewsItem from './NewsItem';
import { useEffect, useState } from 'react';
import axios from '../../node_modules/axios/index';

const NewsListBlock = styled.div`
  box-sizing: border-box;
  padding-bottom: 3rem;
  width: 768px;
  margin: 0 auto;
  margin-top: 2rem;
  @media screen and (max-width: 768px) {
    width: 100%;
    padding-left: 1rem;
    padding-right: 1rem;
  }
`;

const NewsList = () => {
  const [articles, setArticles] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    // async 를 사용하는 함수를 따로 선언
    const fetchData = async () => {
      setLoading(true);
      try {
        const response = await axios.get(
          'https://newsapi.org/v2/top-headlines?country=kr&apiKey=발급한 키값',
        );
        setArticles(response.data.articles);
      } catch (e) {
        console.log(e);
      }
      setLoading(false);
    };
    fetchData();
  }, []);

  // 대기중일때
  if (loading) {
    return <NewsListBlock>대기중...</NewsListBlock>;
  }

  // 아직 article 값이 설정되지 않았을 때
  if (!articles) {
    return null;
  }
  // article 값이 유효할 때
  return (
    <NewsListBlock>
      {articles.map((article) => (
        <NewsItem key={article.url} article={article} />
      ))}
    </NewsListBlock>
  );
};

export default NewsList;

데이터를 불러와서 map 함수를 사용하여 컴포넌트 배열로 변환할 때 꼭 해당 값이 현재 null 이 아닌지 검사해야 합니다. 이 작업을 하지 않으면 아직 데이터가 없을 때 null에는 map함수가 없기 때문에 렌더링 과정에서 오류가 발생합니다. 그래서 애플리케이션이 제대로 나타나지 않고 흰페이지만 보이게 됩니다.

if (!articles) 로 꼭 확인 필요

 

다음 블로그에서는 카테고리 기능을 구현해보겠습니다.

반응형