리액트로 프로젝트를 생성하여 개발하는 과정 중 리액트의 필수 문법 및 기초적인 부분, 심화 과정 등을 정리한 문서입니다. 정리한 부분에는 제가 이해하는 관점에서만 정리를 하였기 때문에 초점은 보여주는 형식이 아닌 제가 필요할 때 사용하려는 목적이 담겨져 있습니다.
자바스크립트, 노드, 리액트들은 비동기 프로그래밍임을 알아야 합니다. 비동기 처리를 위해 Promise 와 Asnyc/await 를 사용하고 있으며, API 데이터를 가져오는 경우에도 비동기적으로 작동하기 때문에 이러한 로직처리를 하기 위해서는 그에 알맞는 함수와 사용법을 이미 알고 있어야 함을 알려드립니다. 본 예제에서는 useReducer와 axios 라이브러리를 이용하여 데이터를 비동기적으로 가져오는 방법에 대해 알아보도록 하겠습니다.
그러면 useReducer 를 이용한 API 활용 에 대해 배워보도록 합시다.
완성된 예제는 다음 링크를 통해 미리 보실 수 있습니다.
https://github.com/libtv/React_Note/tree/master/19.%20api-integrate
# Contents
- useReducer 를 이용한 API 활용
# useReducer 를 이용한 API 활용
새로운 프로젝트를 생성하고 라이브러리를 설치하겠습니다.
아래 명령어를 통해 프로젝트와 라이브러리를 설치합니다.
npx create-creat-app api-integrate
cd api-integrate
npm install --save axios styled-components
우리가 이번에 API 연동 실습을 할 때에는 JSONPlaceholder 에 있는 연습용 API 를 사용해볼 것입니다.
https://jsonplaceholder.typicode.com/users 결과물은 다음과 같은 형식으로 이루어져있습니다.
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "Shanna@melissa.tv",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
}
},
(...)
]
페이지가 로딩 상태일 때에는 로딩중입니다 라는 메시지가 Body 태그에 나오게 되고, axios의 결과 값이 나오는 데로, data를 전송하는 예제를 작성해보았습니다.
아래 코드를 통해 App.js를 수정합니다.
import axios from "axios";
import React, { useCallback, useEffect, useReducer } from "react";
import styled, { css } from "styled-components";
const MyList = styled.h3`
color: red;
font-size: 15px;
`;
const initialState = {
loading: true,
data: null,
};
const MyButton = styled.button`
font-size: 20px;
background-color: aquamarine;
${(props) => {
if (props.visible)
return css`
display: none;
`;
}}
`;
function reducer(state, action) {
switch (action.type) {
case "LOADING":
return {
...state,
loading: true,
};
case "RENDER":
return {
...state,
loading: false,
data: action.data,
};
}
}
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
const { loading, data } = state;
useEffect(async () => {
const response = await axios.get("https://jsonplaceholder.typicode.com/users");
dispatch({
type: "RENDER",
data: response.data,
});
}, [loading]);
const onClick = useCallback(() => {
dispatch({
type: "LOADING",
});
});
return (
<div className="App">
<>
{loading
? "로딩중입니다."
: data.map((list) => {
return (
<MyList>
{list.id} : {list.name} - {list.email}
</MyList>
);
})}
<MyButton onClick={onClick} visible={loading}>
다시 불러오기
</MyButton>
</>
</div>
);
}
export default App;
이처럼 비동기적 API를 사용할 때에는 useEffect 에서 로딩한 데이터를 통해 렌더링 하는 것이 바람직하다고 생각합니다.
데이터가 변경될 때 리렌더링을 제공함으로써 좀 더 유연하고 동적인 페이지를 작성할 수 있습니다.
'오픈소스 > 노드' 카테고리의 다른 글
[Node] React 정리(21) - 리덕스 이론 정리 (0) | 2021.10.26 |
---|---|
[Node] React 정리(20) - useAsync 커스텀 훅 만들기, Context API를 사용하여 useAsync 커스텀 훅 적용 (0) | 2021.10.26 |
[Node] React - TodoList 만들기 (0) | 2021.10.20 |
[Node] React 정리(18) - styled-components (0) | 2021.10.19 |
[Node] Immer 라이브러리를 이용하여 더 쉬운 불변성 관리 (0) | 2021.10.19 |