React api 통신 로딩,에러처리

React api 통신 로딩,에러처리

import React, { useEffect, useState } from "react"; export default function AppProducts() { const [loading, setLoading] = useState(false); const [error, setError] = useState(); const [products, setProducts] = useState([]); const [checked, setChecked] = useState(false); const handleChange = () => setChecked((prev) => !prev); useEffect(() => { setLoading(true); setError(undefined); fetch(`data/${checked ? "sale_" : ""}products.json`) .then((res) => res.json()) .then((data) => { console.log("🔥뜨끈한 데이터를 네트워크에서 받아옴"); setProducts(data); }) .catch((e) => setError("에러가 발생했음!")) .finally(() => setLoading(false)); return () => { console.log("🧹 깨끗하게 청소하는 일들을 합니다."); }; }, [checked]); if (loading) return <p>Loading...</p>; if (error) return <p>{error}</p>; return ( <> <input id="checkbox" type="checkbox" value={checked} onChange={handleChange} /> <label htmlFor="checkbox">Show Only 🔥 Sale</label> <ul> {products.map((product) => ( <li key={product.id}> <article> <h3>{product.name}</h3> <p>{product.price}</p> </article> </li> ))} </ul> </> ); }

커스텀훅으로 분리

hook

import { useEffect, useState } from 'react'; export default function useProducts({ salesOnly }) { const [loading, setLoading] = useState(false); const [error, setError] = useState(); const [products, setProducts] = useState([]); useEffect(() => { setLoading(true); setError(undefined); fetch(`data/${salesOnly ? 'sale_' : ''}products.json`) .then((res) => res.json()) .then((data) => { console.log('🔥뜨끈한 데이터를 네트워크에서 받아옴'); setProducts(data); }) .catch((e) => setError('에러가 발생했음!')) .finally(() => setLoading(false)); return () => { console.log('🧹 깨끗하게 청소하는 일들을 합니다.'); }; }, [salesOnly]); return [loading, error, products]; }

hook 사용

import React, { useState } from 'react'; import useProducts from '../../hooks/use-products'; export default function Products() { const [checked, setChecked] = useState(false); const [loading, error, products] = useProducts({ salesOnly: checked }); const handleChange = () => setChecked((prev) => !prev); if (loading) return <p>Loading...</p>; if (error) return <p>{error}</p>; return ( <> <input id='checkbox' type='checkbox' value={checked} onChange={handleChange} /> <label htmlFor='checkbox'>Show Only 🔥 Sale</label> <ul> {products.map((product) => ( <li key={product.id}> <article> <h3>{product.name}</h3> <p>{product.price}</p> </article> </li> ))} </ul> </> ); }
JP
이중표Frontend Engineer

3년차 프론트엔드 개발자. Next.js, React, TypeScript 기반 웹 애플리케이션 개발 전문. 대규모 트래픽 환경에서 SSR·ISR 렌더링 전략 설계 경험.

이력서 보기