jsonplaceholder에서 데이터를 가져올 때는 fetch메서드를 사용했지만 오늘은 axios라이브러리를 사용해서 코드를 작성해 보았다.
Axios
리액트 애플리케이션에서 HTTP요청 및 응답을 처리해 주는 기능 제공해 주는 라이브러리이다.
1) 터미널에서 axios라이브러리 설치 후 package.json에서 확인
**npm은 install이지만 yarn은 add로 설치한다.
yarn add axios
2) import axios from 'axios'로 가져와서 사용한다.
3) async는 JavaScript에서 비동기 함수를 정의할 때 사용하는 키워드로 await 키워드와 같이 사용한다
4) await은 비동기 함수의 결과가 도착할 때까지 기다리도록 해준다. (async로 정의된 함수 안에서만 사용 가능)
5) axios를 사용해 API를 호출하며 이때 url과 config가 필요하다.
카카오톡 API를 이용한 예제 [도서검색]
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
1. 카카오개발자 센터 API이용
- 내 애플리케이션에서 새로 추가 -> 앱키 -> REST API키 복사 (검색일 때는 rest, 지도는 javascript api사용)
2. 문서에서 API타입 선택 -> 검색 -> REST API
3. 라우터의 get에서 받는 파라미터는 정해져 있다.(문서 참고) - 검색어 변수 query, 페이징 변수는 page
4. 도서검색 샘플 사용
- 문서를 보면 req와 res의 사용법에 대해 적혀있다.
코드 작성 & 분석
import axios from 'axios';
import React, { useEffect, useState } from 'react'
const Component1 = ({title}) => {
const[query,setQuery] = useState('안드로이드');
const[page,setPage] = useState(1);
const[last,setLast] = useState(1);
const [documents,setDocuments] = useState(null);
const callAPI = async() =>{
const url = `https://dapi.kakao.com/v3/search/book?target=title&query=${query}&page=${page}`;
const config = {headers:'Authorization: KakaoAK dc8d40f2136deeecad5055925f2695db'};
const result = await axios(url,config);
setDocuments(result.data.documents);
const total = result.data.meta.pageable_count;
setLast(Math.ceil(total/10))
}
1. axios 라이브러리 설치 후 페이지를 렌더링 할 컴포넌트에 import 해준다.
2. App.js에서 title 속성을 파라미터로 받아 < h1> 태그에 출력
3. API의 데이터를 가져올 callAPI 함수를 생성해 async타입으로 지정해 준 다음 url과 config작성
- url은 api의 주소, config에는 api호출에 필요한 헤더 Authorization을 담아 저장한다.
※ Authorization: 뒤에 한 칸 띄어쓰기 KakaoAK 띄어쓰기 REST API키 (카카오 내 애플리케이션에서 확인)
4. 라우터의 파라미터 들어갈 query와 page는 useState(상태) 변수로 기본값을 지정하여 url의? 뒤에 작성한다.
1) 파라미터 변수를 생성해 url에서 지정
const url = `https://dapi.kakao.com/v3/search/book?target=title&query=${query}&page=${page}`;
2) config변수에 params 속성을 주어 파라미터 지정
const config={
headers:'Authorization: KakaoAK dc8d40f2136deeecad5055925f2695db',
params:{query:query, size:5, page:page} };
5. axios라이브러리 사용해서 api를 호출하고, await으로 호출 결과를 기다린다. -> 결과는 result변수에 저장
6. console.log(result)로 결과를 콘솔창에 출력해 보면 아래와 같이 데이터가 찍힌다.
** 개발자도구(f12)에서 콘솔에 찍힌 결과를 확인해 보면 데이터가 data의 documents에 담겨있는 것을 확인할 수 있다.
7. 결과를 담을 상태변수 documents를 생성해 초기값으로 null을 준다 -> 15번
8. setDocument 함수를 사용해 document 변수에 result.data.documents값을 저장한다.
9. 전체 문서의 개수를 출력할 total 변수에는 result.data.meta.pageable_count를 저장한다.
10. 페이징 변수는 page, 마지막 페이지 변수는 last, input상자의 검색어 변수는 query의 상태변수에 저장한다.
useEffect(()=>{
callAPI();
},[page])
const onSubmit =(e) => {
e.preventDefault();
callAPI();
setPage(1);
}
if(documents===null){
return <h1>로딩중........</h1>
}
11. useEffect 훅을 사용해 렌더링 할 때마다 해줄 작업, callAPI( )를 호출해 준다.
**처음 렌더링 될 때만 호출하기 위해 의존배열 [ ]을 넣어주고 안에 page값을 넣어 페이지에 따라 렌더링 되도록 설정
12. form의 input상자 안에 입력한 검색어를 받아 submit 됐을 때 이벤트 처리해 주는 함수 onSubmit생성
13. submit은 버튼을 누르면 이벤트가 바로 실행되기 때문에 이벤트 변수를 e로 받아 preventDefault로 작업을 먼저 중단해준다.
14. form의 query(검색어) 데이터를 받아 넘겨줘 렌더링 하기 위해 callAPI()를 호출한 다음 페이지를 1로 오게 설정.
15. 데이터를 받아와 저장하는 documents 변수에 값이 들어오지 않았을 경우 사용자에게 알려주기 위해 로딩 중 문구를 리턴한다.
return (
<div>
<h1>{title}</h1>
<form onSubmit={onSubmit}>
<input type="text" placeholder='검색어' value={query} onChange={(e)=>setQuery(e.target.value)}/>
<button>검색</button>
</form>
<div className='documents'>
{documents.map(d=>(
<div className='box'>
<img src={d.thumbnail ? d.thumbnail:'http://via.placeholder.com/120X150'} alt="" />
<div className='ellipsis'>{d.title}</div>
</div>
))}
</div>
<div>
<button onClick={()=>setPage(page-1)} disabled={page===1}>이전</button>
<span style={{margin:'10px'}}>{page}/{last}</span>
<button onClick={()=>setPage(page+1)} disabled={page===last}>다음</button>
</div>
</div>
)
}
export default Component1
16. return문 안에는 렌더링 할 페이지를 구상하여 태그를 작성한다 - 크게 4가지(타이틀, 검색상자, 도서목록, 페이징버튼)
타이틀
17. App.js에서 props로 준 title을 h1태그에 넣어 출력
검색상자
18. form태그에 input타입 text상자와 submit 할 버튼을 그려준다. (form안의 버튼은 지정하지 않아도 submit버튼이다)
19. input의 value에다 상태변수 query를 주어 기본값으로 상자에 뜨도록 설정해 준다.
** 검색창에 입력한(value) 값에 따라 query가 변경되어 callAPI에서 검색어에 해당하는 데이터를 출력해 준다.
20. value에 기본값을 주게 되면 검색박스 안의 값을 변경할 수 없어 onChange이벤트를 준다.
21. onChange 함수 - 이벤트변수 e를 받아 setQuery함수로 쿼리값을 e.target.value(입력한 값)으로 변경
도서목록
22. form태그의 onSubmit(기본) 이벤트를 주고 만들어둔 onSubmit이벤트를 담아준다.
23. API호출로 가져온 데이터가 담긴 documents 변수에다 map함수를 이용하여 데이터를 하나씩 쪼개 변수 d에 담아준다
24. 썸네일 이미지는 thumbnail키에, 타이틀은 title키에 담겨 있어 d.thumbnail과 d.title로 각각 선택해 출력
25. 이미지가 존재하지 않을 경우 삼항연산자를 이용해 false일 때 더미이미지를 출력해 준다
페이징버튼
26. 아래 페이징을 위한 버튼과 페이지번호를 보여줄 span태그를 생성한다.
27. 버튼 클릭 시 페이지 번호가 바뀌도록 onClick이벤트에 setPage함수를 사용해 값을 변경해 준다.
** {( )=>setPage(page+1)}과 같은 형태를 익명함수라고 하며 ( )=> 부분을 생략하면 값이 계속해서 증가한다.
28. 페이지가 1일 경우, last일 경우 이전과 다음 버튼의 disabled속성에 조건을 주어 페이지이동이 되지 않도록 막아준다.
** { } 괄호 안이 true일 경우 실행되기 때문에 삼항연산자를 사용하지 않아도 된다.
App.js코드
import logo from './logo.svg';
import './App.css';
import Component from './Components/Component1';
function App() {
return (
<div className="App">
<Component title='도서검색'/>
</div>
);
}
export default App;
css
.documents{
display: grid;
grid-template-columns: repeat(5,1fr);
}
.box{
border: 1px solid gray;
margin: 10px;
padding: 10px 5px;
border-radius: 10px;
border-bottom: 3px solid gray;
}
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
input[type='text']{
padding: 2px;
margin: 10px 5px 10px 0px;
}
button{
background-color: rgb(88, 61, 188);
color: white;
border: none;
padding: 5px;
border-radius: 10px;
}
button:disabled{
background-color: gray;
}
'FE > React' 카테고리의 다른 글
React Context API 사용법 및 Props와 Context차이점 (0) | 2023.03.16 |
---|---|
리액트로 라우터 생성하기 (react-router-dom & qs 라이브러리) (0) | 2023.03.09 |
HTML의 DOM과 JavaScript의 관계 & React의 탄생 (0) | 2023.03.05 |
React 리액트 기초 (jsx파일, 컴포넌트, 함수 자동완성 라이브러리 ES7+) (0) | 2023.02.27 |
React란? cmd 리액트 설치 및 실행 (VScode) - yarn (0) | 2023.02.27 |