코리아 IT아카데미/react.js
8일차 | API로 users 목록 불러오기, user 정보 나타내기
Sharon kim
2022. 3. 23. 12:02
yarn add axios
|
yarn add react-async |
App.js
import React from 'react';
import Users from './components/users';
//yarn add axios
//https://jsonplaceholder.typicode.com/users
function App() {
return (
<Users/>
);
}
export default App;
useAsync.js
import {useReducer, useEffect} from "react";
function reducer(state, action) {
switch (action.type) {
case "LOADING":
return {
loading: true,
data: null,
error: null,
};
case "SUCCESS":
return {
loading: false,
data: action.data,
error: null,
};
case "ERROR":
return {
loading: false,
data: null,
error: action.error,
};
default:
throw new Error("${action.type} 예외발생!");
}
}
function useAsync(callback, deps = [], skip = false) {
const [state, dispatch] = useReducer(reducer, {
loading: false,
data: null,
error: null,
});
const fetchData = async () => {
dispatch({type: "LOADING"});
try {
const data = await callback();
dispatch({type: "SUCCESS", data});
} catch (e) {
dispatch({type: "ERROR", error: e});
}
};
useEffect(() => {
if (skip) return;
fetchData();
}, deps);
return [state, fetchData];
}
export default useAsync;
user.jsx
import React from "react";
import axios from "axios";
import useAsync from "../useAsync";
async function getUsers(id) {
const response = await axios.get(
`https://jsonplaceholder.typicode.com/users/${id}`
);
return response.data;
}
function User({id}) {
const [state] = useAsync(() => getUsers(id), [id]);
const {loading, data: user, error} = state;
if (loading) return <div>로딩중...</div>;
if (error) return <div>에러가 발생!!!</div>;
if (!user) return null;
return (
<div>
<h2>{user.username}</h2>
<p>
<b>Email : </b> {user.email}
</p>
</div>
);
}
export default User;
users.jsx
import React, {useState} from "react";
import axios from "axios";
import useAsync from "../useAsync";
import User from "./user";
// useAsync에서는 Promise의 결과 바로 data에 담기 때문에, 요청을 한 이후 response에서 data 추출하여 반환하는 함수를 따로 만듬
async function getUsers() {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
return response.data;
}
function Users() {
const [userId, setUserId] = useState(null);
const [state, refetch] = useAsync(getUsers, [], true);
const {loading, data: users, error} = state;
if (loading) return <div>로딩중...</div>;
if (error) return <div>에러가 발생!!!</div>;
if (!users) return <button onClick={refetch}>불러오기</button>;
return (
<>
<ul>
{users.map((user) => (
<li
key={user.id}
onClick={() => setUserId(user.id)}
style={{cursor: "pointer"}}
>
{user.username} ({user.name})
</li>
))}
</ul>
<button onClick={refetch}>다시 불러오기</button>
{userId && <User id={userId} />}
</>
);
}
export default Users;
index.css
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}