Stack/React
[React] API 연동하기 2
7ingout
2022. 6. 29. 12:09
App.js
import './App.css';
import UserCustomHook from './components/UsersCustomHook';
// import Posts from './components/Posts';
// import PostsReducer from './components/PostsReducer';
// import Users from './components/Users';
// import UsersReducer from './components/UsersReducer';
function App() {
return (
<div className="App">
{/* <Users/>
<UsersReducer/>
<Posts/>
<PostsReducer/> */}
<UserCustomHook/>
</div>
);
}
export default App;
components/UsersCustomHook.js
// useAsync를 사용해서 비동기 전송을 받아와 사용
import React, { useState } from 'react';
import axios from 'axios';
import useAsync from './useAsync';
import User from './User';
async function getUsers() {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
return response.data;
}
const UserCustomHook = () => {
const [userId, setUserId] = useState(null);
const [state, refetch] = useAsync(getUsers, [], true);
const { loading, data, error } = state;
if(loading) return <div>로딩중...</div>
if(error) return <div>에러가 발생했습니다.</div>
if(!data) return <button onClick={refetch}>불러오기</button>
return (
<div>
<ul>
{data.map(user => (
<li key={user.id} onClick={()=>{
setUserId(user.id)
}}>
{user.username} ({user.name})
</li>
)
)}
</ul>
<button onClick={refetch}>다시 불러오기</button>
{userId && <User id = {userId}/>}
</div>
);
};
export default UserCustomHook;
components/useAsync.js
import { useReducer, useEffect } from 'react';
const initialState = {
loading: false,
data: null,
error: null
}
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:
return state;
}
}
function useAsync(callback, deps = [], skip = false) {
const [ state, dispatch ] = useReducer(reducer, initialState);
const fetchDate = async () => {
dispatch({ type: "LOADING" });
try{
const data = await callback();
dispatch({
type: "SUCCESS",
data: data
})
}
catch(e) {
dispatch({
type: "ERROR",
error: e
})
}
}
useEffect(()=>{
// skip이 true면 리턴 fetchDate() 실행안됨
if(skip) return;
fetchDate();
// ↓ eslint 설정을 다음 줄에서만 비활성화
// eslint-disable-next-line
}, deps)
return [state, fetchDate];
}
export default useAsync;
Components/User.js
import React from 'react';
import axios from 'axios';
import useAsync from './useAsync';
async function getUser(id) {
const response = await axios.get(
`https://jsonplaceholder.typicode.com/users/${id}`
);
return response.data;
}
const User = ({id}) => {
const [ state ] = useAsync(()=> getUser(id), [id]);
const { loading, data, error } = state;
if(loading) return <div>로딩중...</div>
if(error) return <div>에러가 발생했습니다.</div>
if(!data) return null
return (
<div>
<h2>{data.username}</h2>
<p>
Email: {data.email}
</p>
</div>
);
};
export default User;
.
.
.
2022.06.28 - [Coding/React] - [React] API 연동하기