B-2 과제 ①번: API 주소를 바꿔서 다른 데이터 불러오기
✅ 목표
https://jsonplaceholder.typicode.com/users
주소에서 사용자 목록을 불러오기
- 로딩 중 / 에러 / 정상 표시 모두 구현
- 기본 구조는
PostList
와 동일
📄 UserList.jsx
– 사용자 목록 컴포넌트
import { useEffect, useState } from 'react';
function UserList() {
const [users, setUsers] = useState([]); // 사용자 데이터
const [loading, setLoading] = useState(true); // 로딩 상태
const [error, setError] = useState(null); // 에러 상태
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then((res) => {
if (!res.ok) throw new Error('사용자 데이터를 불러오는 데 실패했습니다');
return res.json();
})
.then((data) => setUsers(data))
.catch((err) => setError(err.message))
.finally(() => setLoading(false));
}, []);
if (loading) return <p>👀 사용자 정보를 불러오는 중...</p>;
if (error) return <p>❌ 에러: {error}</p>;
return (
<ul>
{users.map((user) => (
<li key={user.id}>
<strong>{user.name}</strong> ({user.email})<br />
📍 {user.address.city}
</li>
))}
</ul>
);
}
export default UserList;
📄 App.jsx
에서 사용하기 (PostList 대신)
import UserList from './components/UserList';
function App() {
return (
<div style={{ padding: '2rem' }}>
<h1>👤 사용자 목록 불러오기</h1>
<UserList />
</div>
);
}
export default App;
🧪 실행 결과
항목 |
설명 |
https://jsonplaceholder.typicode.com/users |
사용자 10명의 정보 가져옴 |
표시 내용 |
이름, 이메일, 도시명(city) |
|
|
B-2 과제 ②번: useFetch()
커스텀 훅 만들기
✅ 목표
항목 |
설명 |
공통 로직 |
fetch , loading , error , data 상태 처리 |
재사용성 |
어떤 URL이든 쉽게 사용 가능 |
적용 예시 |
사용자 목록, 게시글 목록 등에서 사용 가능 |
📁 폴더 구조
src/
├── hooks/
│ └── useFetch.js
├── components/
│ └── UserList.jsx
│ └── PostList.jsx
📄 1. hooks/useFetch.js
import { useEffect, useState } from 'react';
function useFetch(url) {
const [data, setData] = useState(null); // 받아온 데이터
const [loading, setLoading] = useState(true); // 로딩 여부
const [error, setError] = useState(null); // 에러 여부
useEffect(() => {
let ignore = false; // 언마운트 방지용 플래그
fetch(url)
.then((res) => {
if (!res.ok) throw new Error('데이터 불러오기 실패');
return res.json();
})
.then((data) => {
if (!ignore) setData(data);
})
.catch((err) => {
if (!ignore) setError(err.message);
})
.finally(() => {
if (!ignore) setLoading(false);
});
return () => {
ignore = true;
};
}, [url]);
return { data, loading, error };
}
export default useFetch;
📄 2. UserList.jsx
– useFetch 적용 예시
import useFetch from '../hooks/useFetch';
function UserList() {
const { data: users, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');
if (loading) return <p>로딩 중...</p>;
if (error) return <p>에러 발생: {error}</p>;
return (
<ul>
{users.map((user) => (
<li key={user.id}>
<strong>{user.name}</strong> ({user.email})<br />
📍 {user.address.city}
</li>
))}
</ul>
);
}
export default UserList;
📄 3. PostList.jsx
– 게시글 API에도 재사용 가능
import useFetch from '../hooks/useFetch';
function PostList() {
const { data: posts, loading, error } = useFetch('https://jsonplaceholder.typicode.com/posts?_limit=5');
if (loading) return <p>로딩 중...</p>;
if (error) return <p>에러 발생: {error}</p>;
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<strong>{post.title}</strong>
<p>{post.body}</p>
</li>
))}
</ul>
);
}
export default PostList;
✅ 장점 요약
항목 |
설명 |
재사용성 |
URL만 바꾸면 여러 곳에서 동일한 fetch 처리 가능 |
유지보수 |
공통 로직이 한 곳에 집중되어 관리 편리 |
테스트 용이 |
훅 단위로 테스트 가능 |
GitHub - heroyooi/react-app at bs2_resolve
B-2 과제 ③번: 버튼 클릭 시 API 호출
🎯 목표
항목 |
설명 |
트리거 방식 |
useEffect 자동 호출 → ❌ / 버튼 클릭 시 수동 호출 → ✅ |
적용 대상 |
게시글 목록 또는 사용자 목록 |
구현 방식 |
버튼 클릭 시 fetch() 실행, 결과 표시 |
📁 예시 파일 구성
src/
├── components/
│ └── PostFetcher.jsx
📄 PostFetcher.jsx
– 버튼 클릭으로 fetch 실행
import { useState } from 'react';
function PostFetcher() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const handleFetchPosts = async () => {
setLoading(true);
setError(null);
try {
const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=5');
if (!res.ok) throw new Error('게시글을 불러오지 못했습니다.');
const data = await res.json();
setPosts(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
return (
<div>
<h2>📰 게시글 불러오기</h2>
<button onClick={handleFetchPosts}>게시글 가져오기</button>
{loading && <p>로딩 중...</p>}
{error && <p style={{ color: 'red' }}>에러: {error}</p>}
<ul>
{posts.map((post) => (
<li key={post.id}>
<strong>{post.title}</strong>
<p>{post.body}</p>
</li>
))}
</ul>
</div>
);
}
export default PostFetcher;
📄 App.jsx
에서 사용 예시
import PostFetcher from './components/PostFetcher';
function App() {
return (
<div style={{ padding: '2rem' }}>
<h1>🖱 버튼 클릭으로 API 호출</h1>
<PostFetcher />
</div>
);
}
export default App;
✅ 작동 흐름
- 초기에는 아무것도 불러오지 않음
- 사용자가 "게시글 가져오기" 버튼 클릭 시 fetch 실행
- 성공 시 목록 표시, 실패 시 에러 표시
GitHub - heroyooi/react-app at bs2_resolve2
💬 댓글
※ 로그인 후 댓글을 작성할 수 있습니다.