반응형
pp.325 ~ pp.333
(아래 레포지토리에서 ch04_4 에 해당 하는 내용.)
https://github.com/yisj777s/doit-react-webapp-typescript
GitHub - yisj777s/doit-react-webapp-typescript: Do it! 리액트 개발자라면 이렇게 해야 인정받는다! 리액트로
Do it! 리액트 개발자라면 이렇게 해야 인정받는다! 리액트로 웹앱 만들기 with 타입스크립트 - GitHub - yisj777s/doit-react-webapp-typescript: Do it! 리액트 개발자라면 이렇게 해야 인정받는다! 리액트로 웹
github.com
※ 자세한 내용은 Backend 쪽에서 ...
fetch는 네트워크 요청을 위한 Web API, promise는 비동기 작업에 대해 완료 또는 실패를 반환
예시
fetch("htttps://randomuser.me/api/') // api URL
.then(res => res.json()) // res: response; json파일로 받아옴
.then((data: unknown) => { // data를 받아와서 results에 넣음
const { results } = data as { results: IRandomUser[] }
const user = convertRandomUser(result[0])
실습 - 버튼을 누르면 랜덤으로 유저 프로필 카드를 받아오는 기능
더보기
src/data/fetchRandomUser.ts
import { resolve } from "path";
export type IRandomUser = {
email: string
name: { title: string; first: string; last: string }
picture: { large: string }
}
const convertRandomUser = (result: unknown) => {
const { email, name, picture } = result as IRandomUser
return { email, name, picture }
}
export const fetchRandomUser = (): Promise<IRandomUser> =>
new Promise((resolve, reject) => {
fetch('https://randomuser.me/api/')
.then(res => res.json())
.then((data: unknown) => {
console.log(data)
const { results } = data as { results: IRandomUser[] }
resolve(convertRandomUser(results[0]));
})
.catch(reject)
})
src/data/index.ts
export * from './util'
export * from './image'
export * from './chance'
export * from './date'
export * from './User'
export * from './Card'
export * from './fetchRandomUser'
src/pages/FetchTest.tsx
import { useState, useCallback, useEffect } from "react";
import { useToggle } from "../hooks";
import { Title, Avatar, Icon } from "../components";
import { Button } from "../theme/daisyui";
import * as D from '../data'
export default function FetchTest() {
const [loading, toggleLoading] = useToggle()
const [randomUser, setRandomUser] = useState<D.IRandomUser | null>(null)
const [error, setError] = useState<Error | null>(null)
const getRandomUser = useCallback(() => {
toggleLoading()
D.fetchRandomUser().then(setRandomUser).catch(setError).finally(toggleLoading)
}, [toggleLoading])
useEffect(getRandomUser, [getRandomUser])
return (
<section className="mt-4">
<Title>FetchTest</Title>
<div className="flex justify-center mt-4">
<Button className="btn-sm btn-primary" onClick={getRandomUser}>
<Icon name="get_app"/>
<span>get random user</span>
</Button>
</div>
{loading && (
<div className="flex items-center justify-center">
<Button className="btn-circle loading"></Button>
</div>
)}
{error && (
<div className="p-4 mt-4 bg-red-200">
<p className="text-3xl text-red-500 text-bold">{error.message}</p>
</div>
)}
{randomUser && (
<div className="flex justify-center p-4 mt-4">
<Avatar src={randomUser.picture.large} />
<div className="ml-4">
<p className="text-xl text-bold">
{randomUser.name.title} {randomUser.name.first} {randomUser.name.last}
</p>
<p className="italic text-gray-600">{randomUser?.email}</p>
</div>
</div>
)}
</section>
)
}
src/App.tsx
import FetchTest from "./pages/FetchTest"
export default function App() {
return (
<main>
<FetchTest />
</main>
)
}
실습했던 코드는 아래에서 확인 가능.
https://codesandbox.io/p/sandbox/fetch-promise-practice-forked-nqwtjk

반응형
'Front-End > React' 카테고리의 다른 글
| React #24 (Redux - 리듀서 활용) (1) | 2025.07.22 |
|---|---|
| React #23 (훅, 상태관리 - 내장 useReducer vs Redux 패키지) (1) | 2025.07.22 |
| React #21 (고급 훅 - useId, useTransition, useImperativeHandle) (1) | 2025.07.21 |
| React #20 (고급 훅 - useLayoutEffect) (1) | 2025.07.21 |
| React #19 (렌더 최적화 훅 - useMemo, useCallback) (3) | 2025.07.21 |