엘리스 AI 트랙 08주차 - OpenAPI 심화 (2/20)🔥
✔ 08주차. Open API 활용
<학습 목표>
-
React로 제작한 웹 사이트에서 Redux를 활용해 상태관리를 수행할 수 있습니다.
-
Axios를 이용하여 Create, Read, Update, Delete 를 할 수 있습니다.
-
OpenAPI를 활용하여 React로 제작한 웹 사이트에 사용할 수 있습니다.
[01 API 사용법 익히기]
1. 비동기 처리
- 비동기 처리를 하기 위해서 .then을 이용한 콜백 함수를 자주 사용하면 가독성이 나빠짐
axios.get(`요청할 url 1`)
.then(res => axios.get(`요청할 url 2`))
.then(res => {
const ps = res.data.map(user => axios.get(`요청할 url 3`));
···
})
.then(ress => ···)))
.then(repoArrs => {
···
}
···
})
- 위와 같은 예를 콜백 지옥이라고 하는데, 콜백지옥을 벗어나기 위해 async와 await를 이용함 (콜백 함수와 .then을 사용하지 않고 비동기 처리)
- async / await
- Promise : 비동기 처리에서 사용되는 객체, Promise가 상태를 관리함으로써 다른 코드가 비동기적으로 실행될 수 있도록 해주는 객체
- async : 해당 함수에서 비동기 처리를 위한 Promise 동작을 한다는 것을 명시함,
- await : 호출되는 함수가 적절한 결과를 반환할 때까지 기다리도록 동작합니다.
→ 실질적인 동작은 await, await을 사용하기 위해 async를 명시
import React from 'react';
import axios from 'axios';
class Users extends React.Component {
constructor() {
super();
this.state = { users: [] };
}
// async 추가
async componentDidMount() {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
this.setState({ users : response.data })
}
render() {
const userName = this.state.users.map(
(user) => (<li key={user.id}> {user.name} </li>)
);
return (
<>
<h4>사용자 리스트</h4>
<div> {userName} </div>
</>
);
}
}
export default Users;
- Hook으로 API 다루기
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function Users() {
const [users, setUsers] = useState([]);
// async와 await를 이용한 useEffect()
useEffect(() => {
async function fetch() {
const response = await axios.get( 'https://jsonplaceholder.typicode.com/users' );
setUsers(response.data);
};
fetch();
}, []);
const userName = users.map(
(user) => (<li key={user.id}> {user.name} </li>)
);
return (
<>
<h4>사용자 리스트</h4>
<div>{userName}</div>
</>
);
}
export default Users;
- API 호출 에러 핸들링
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function Users() {
const [users, setUsers] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchUser() {
try {
const response = await axios.get(
'https://jsonplaceholder.typicode.com/error'
);
setUsers(response.data);
} catch(e) {
setError(e);
}
};
fetchUser();
}, []);
const userName = users.map(
(user) => (<li key={user.id}> {user.name} </li>)
);
if (error) return <h4>에러 발생!</h4>;
return (
<>
<h4>사용자 리스트</h4>
<div> {userName} </div>
</>
);
}
export default Users;
- 버튼으로 API 호출
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function Users() {
const [users, setUsers] = useState([]);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
}, []);
async function fetchUser() {
// 함수가 처음 시작할 때 loading state를 true, 끝날 때 false
setLoading(true)
try {
const response = await axios.get(
'https://jsonplaceholder.typicode.com/users'
);
setUsers(response.data);
} catch (e) {
setError(e);
}
setLoading(false)
};
const clickHandler = (e) => {
e.preventDefault();
fetchUser();
}
const userName = users.map(
(user) => (<li key={user.id}> {user.name} </li>)
);
if(loading)
return <h4>로딩중...</h4>;
if (error) return <h4>에러 발생!</h4>;
return (
<>
<h4>사용자 리스트</h4>
<div> {userName} </div>
<button onClick={clickHandler}>다시 불러오기</button>
</>
);
}
export default Users;
[02 OpenAPI 활용하기]
1. 포켓몬 API
- 포켓몬 API : Pokémon 메인 게임 시리즈에 등장하는 포켓몬들에 대한 모든 것을 자세히 설명하는 API
- 포켓몬 API 특징과 구조
① HTTP GET 요청으로 API의 자원을 사용할 수 있음
② 사용자가 입력한 값에 따라 포켓몬 이미지, 이름, 높이, 무게 정보를 확인
③ 포켓몬 API에 없는 값 입력 시 404 에러 반환
2. API 요청 함수 만들기
- axios.get() 에 { cancelToken: new axios.CancelToken(c => cancel = c) }을 함께 넘겨야함 (cancelToken : Axios에서 제공하는 것으로 API 요청을 취소하는데 사용되는 토큰)
// PokemonList.js
import React from 'react'
export default function PokemonList({ pokemon }) {
return (
<div>
{pokemon.map(p => (
<div key={p}>{p}</div>
))}
</div>
)
}
// Pagination.js
import React from 'react'
export default function Pagination({ gotoNextPage, gotoPrevPage }) {
return (
<div>
{gotoPrevPage && <button onClick={gotoPrevPage}>Previous</button>}
{gotoNextPage && <button onClick={gotoNextPage}>Next</button>}
</div>
)
}
// app.js
import React, { useState, useEffect } from 'react';
import axios from 'axios'
import PokemonList from './PokemonList'
import Pagination from './Pagination';
function App() {
const [pokemon, setPokemon] = useState([])
const [currentPageUrl, setCurrentPageUrl] = useState("https://pokeapi.co/api/v2/pokemon")
const [nextPageUrl, setNextPageUrl] = useState("")
const [prevPageUrl, setPrevPageUrl] = useState("")
const [loading, setLoading] = useState(true)
const [] = useState()
useEffect(() => {
setLoading(true)
let cancel
// axios.get()으로 currentPageUrl와 cancelToken을 함께 넘기고 state 설정
axios.get(currentPageUrl, { cancelToken: new axios.CancelToken(c => cancel = c) })
.then(response => {
console.log(response)
setPokemon(response.data.results.map(p => p.name));
setNextPageUrl(response.data.next)
setPrevPageUrl(response.data.previous)
setLoading(false)
})
// 페이지 이동이 취소되면 현재 페이지 유지
return () => cancel()
}, [currentPageUrl])
function gotoNextPage() {
setCurrentPageUrl(nextPageUrl)
}
function gotoPrevPage() {
setCurrentPageUrl(prevPageUrl)
}
if (loading) return "로딩중..."
return (
<>
<PokemonList pokemon={pokemon} />
<Pagination
gotoNextPage={nextPageUrl ? gotoNextPage : null}
gotoPrevPage={prevPageUrl ? gotoPrevPage : null}
/>
</>
);
}
export default App;
※ 수업 자료의 출처는 K-Digital Training x 엘리스 인공지능 서비스 개발 기획 1기 (elice.io/)입니다.