axios(필수)
브라우저와 node.js에서 사용할 수 있는 Promise 기반 HTTP 클라이언트 라이브러리
API: 요청 메소드
GET: 데이터조회
POST: 데이터등록
PUT: 데이터수정
DELETE: 데이터 제거
axios 사용법
npm 사용하기:
$ npm install axios
import axios from 'axios';
axios.get('/users/1')
axios.post('경로',{username:"green",id:"aa"})
useState,useEffect로 데이터 로딩하기
상태관리
1.요청의결과 - null
2.로딩상태 - false
3.에러 - null
로딩상태가 true 면 로딩중 하면을 보여줌
에러가 null이 아니면 에러가 발생했습니다 화면을 나타냄
결과값이 없으면 null을 보여줌
로딩이 false 이고 에러가 null이고 결과값이 null이 아닐때 받아온 데이터를 화면에 나타냄
App.js
import "./styles.css";
import { useEffect, useState } from "react";
import axios from "axios";
export default function App() {
const [data, setdata] = useState(null); //data상태값
const [loading, setloading] = useState(false); //loading상태값
const [error, seterror] = useState(null); //
useEffect(() => {
const fetchUsers = async () => {
try {
//요청이 시작되면 error 와 users를 초기화
seterror(null); //에러 아직 없음
setdata(null); //데이터 아직 없음
//loading상태는 true로 변경
setloading(true); //로딩중
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
setdata(response.data);
} catch (e) {
seterror(e);
console.error(e);
}
setloading(false);
};
fetchUsers();
}, []);
if (loading) return <div>로딩중...</div>;
if (error) return <div>에러가 발생했습니다.</div>;
if (!data) return null;
return (
<div className="App">
{data.map((data) => (
<li key={data.id}>
{data.username} {data.name}
</li>
))}
</div>
);
}
loading이 true이면 로딩중
error에 값이 담겨있으면 에러가 발생했습니다.
data에 데이터가없으면 null을 리턴해준다.
useEffect(() => {
const fetchUsers = async () => {
try {
//요청이 시작되면 error 와 users를 초기화
seterror(null); //에러 아직 없음
setdata(null); //데이터 아직 없음
//loading상태는 true로 변경
setloading(true); //로딩중
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
setdata(response.data);
} catch (e) {
seterror(e);
console.error(e);
}
setloading(false);
};
fetchUsers();
}, []);
useEffect로 처음에 마운트될때만 자료를 받아오게해준다. async await으로 비동기문을 만들어주고 try catch로 혹시나 로딩이 정상적으로 이루어지지않았을때 에러처리를 해준다.
response에 await axios.get(주소를받아올서버주소) // 이렇게 입력해준다 서버주소는 Jsonplaceholder에서 받아왔다.
이제 이 코드를 좀 더 간결하게 만들어 보겠다.
useReducer를 사용해서 상태를 관리해주는 코드로 변경
import "./styles.css";
import { useEffect, useReducer } from "react";
import axios from "axios";
const initialstate = {
data: null,
error: null,
loading: false
};
//reducer 함수
function reducer(state, action) {
switch (action.type) {
case "LOADING":
return {
data: null,
error: null,
loading: true
};
case "SUCCESS":
return {
data: action.data,
error: null,
loading: false
};
case "ERROR":
return {
data: null,
error: action.error,
loading: false
};
default:
return state;
}
}
export default function App() {
// const [data, setdata] = useState(null);
// const [loading, setloading] = useState(false);
// const [error, seterror] = useState(null);
const [state, dispatch] = useReducer(reducer, initialstate);
const { data, error, loading } = state;
useEffect(() => {
const fetchUsers = async () => {
try {
dispatch({
type: "LOADING"
});
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
dispatch({
type: "SUCCESS",
data: response.data
});
} catch (e) {
dispatch({
type: "ERROR",
error: e
});
console.error(e);
}
};
fetchUsers();
}, []);
if (loading) return <div>로딩중...</div>;
if (error) return <div>에러가 발생했습니다.</div>;
if (!data) return null;
return (
<div className="App">
{data.map((data) => (
<li key={data.id}>
{data.username} {data.name}
</li>
))}
</div>
);
}
useState로 줬던 상태값들을 useReducer로 하나로묶어주었고 상태변경도 dispatch를 통해서 하도록 바꿨다.
이제여기서 주소에서 값을 받아오는 async await 문을 따로 커스텀 react훅으로 빼서 다른 컴포넌트에서도 주소만 바꿔서 이용할수 있게 만들어주겠다.
useAsync.js
import { useReducer, useEffect } from "react";
//초기값
const status = {
data: null,
loading: false,
error: null
};
//reducer 함수
function reducer(state, action) {
switch (action.type) {
case "LOADING":
return {
data: null,
error: null,
loading: true
};
case "SUCCESS":
return {
data: action.data,
error: null,
loading: false
};
case "ERROR":
return {
data: null,
error: action.error,
loading: false
};
default:
return state;
}
}
const useAsync = (callback, deps = []) => {
// callback함수와 deps배열을 받아옴 //
const [state, dispatch] = useReducer(reducer, status);
// async aswait
const fetchUsers = async () => {
try {
dispatch({
type: "LOADING"
});
const response = await callback(); //callback 함수는 axios.get(주소) 를 리턴
dispatch({
type: "SUCCESS",
data: response.data
});
} catch (e) {
dispatch({
type: "ERROR",
error: e
});
}
};
useEffect(() => {
fetchUsers();
}, deps);
return [state, fetchUsers]; //상태값과 fetchUsers를 돌려줌
};
export default useAsync;
callback함수에 담기는값
async function getUser() {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
return response;
}
response 를 리턴해주는 비동기 함수를 담는다. useAsync에서 실행시키고 결과값을 response에 저장한다음 data에 담아준다.
useAsync가 다 돌아가면 state와 fetchUsers함수를 리턴해준다.
App.js
import "./styles.css";
import axios from "axios";
import useAsync from "./Hooks/useAsync";
async function getUser() {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
return response;
}
export default function App() {
const [state, refetch] = useAsync(getUser, []);
const { data, error, loading } = state;
if (loading) return <div>로딩중...</div>;
if (error) return <div>에러가 발생했습니다.</div>;
if (!data) return null;
return (
<div>
<ul>
{data.map((user) => (
<li ket={user.id}>
{user.username} {user.name}
</li>
))}
</ul>
<button onClick={refetch}>재요청</button>
</div>
);
}
이렇게 서버에서 값을 받아오는 axios에 대해서 배웠다. 또 함수를 묶어서 커스텀hook을 만들어서 사용할수도 있다는걸 알게되었다 물론 아직 스스로 이런걸 짤수있는 능력은 없지만 읽어서 어떻게 돌아가는지는 아니까 잘 찾아서 따라할수있지않을까? axios는 promise를 기반으로 만들어졌기때문에 async await 말고도 .then으로도 사용할수 있다. 일단 이런건 쓸려면 자바스크립트가 기초가되야되는데 이번에 비동기함수를 보면서 자바스크립트에서 부족한점을 알게된것같다.
'프론트엔드 정복기 > 리액트' 카테고리의 다른 글
[React] 20 리액트 라우터 라이브러리 (react-router v6) (0) | 2023.01.19 |
---|---|
[React]19 아이콘 컴포넌트 (react-icons) (0) | 2023.01.18 |
[React]17 상태관리2(useReducer) (0) | 2023.01.17 |
[React]16 성능최적화2 (useCallback) (0) | 2023.01.16 |
[React]15 리액트 성능 최적화(useMemo) (0) | 2023.01.12 |