본문 바로가기

React/TIL

useEffect에서 async/await 사용하고 싶다면?

 

 

컴포넌트가 화면에 보이는 시점에 API 요청하고 싶다면

useEffect를 사용 (컴포넌트가 처음 렌더링 되는 시점에 API 요청)

 

 

여기서 주의할 점

useEffect에 등록하는 함수에 async를 붙이면 안된다!!!!

왜냐하면, useEffect에서 반환해야 하는 값은 뒷정리 함수이기 때문

 

useEffect 내부에서 async/await를 사용하고 싶다면

함수 내부에 async 키워드가 붙은 또 다른 함수를 만들어서 사용해야 한다!

 

 

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(
          `http://newsapi.org/v2/top-headlines?country=kr&apiKey=${API_KEY}`
        );
        setArticles(response.data.articles);
      } catch (e) {
        console.log(e);
      }
      setLoading(false);
    };
    fetchData();
  }, []);

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

  //아직 articles 값이 설정되지 않았을 때
  if (!articles) {
    return null;
  }

  //articles 값이 유효할 때
  return (
    <NewsListBlock>
      {articles.map((article) => (
        <NewsItem key={article.url} article={article} />
      ))}
    </NewsListBlock>
  );
};

 

 

+

데이터를 불러와서 

뉴스데이터 배열을

map 함수를 사용해서

Component 배열로 변환할 때

주의점!

 

map 함수를 사용하기 전에 꼭꼭꼭 !articles를 확인해서

해당값이 현재 null인지 아닌지 확인해야 한다!

만약 이 작업을 하지 않았는데

articles가 null인 상태면 

당연히 map 함수를 사용할 수 없고

렌더링 과정에서 오류가 발생 -> 흰 페이지..

 

 

 

 

 

 

 

 

출처: 김민준, 리액트를 다루는 기술 (개정팜), 2019년, 372쪽

 

 

 

 

----------------------------------------------------------------------------------------------------------------------

data를 fetch하는 함수를 밖에 따로 만드는 방법

	const [loading, setLoading] = useState(true);
	const [tours, setTours] = useState([]);

	const fetchTours = async () => {
		setLoading(true);

		try {
			const response = await fetch(url);
			const tours = await response.json();
			setTours(tours);
			setLoading(false);
		} catch (error) {
			setLoading(false);
			console.log(error);
		}
	};

	useEffect(() => {
		fetchTours();
	}, []);