이번에는 React를 사용할때 서버에서 데이터를 가져오는 방식에 대해서 조사해보려고 한다.
Fetch API라고도 하는데 Javascript 내장 객체로서 RestAPI요청을 처리할수 있다.
fetch()의 경우 window객체에 포함되어있기 때문에 window.fetch()로 사용되기도 한다.
import React, { useState, useEffect } from 'react';
const App = () => {
const [data, setData] = useState(null);
useEffect(() => {
const onLoad = async () => {
const res = await fetch('http://api.com/data');
if(res.ok) {
setData(res.json());
} else {
//{에러처리}
}
}
}, []);
return (<span>{JSON.stringify(data)}</span>);
}
export default App;
import React, { useState, useEffect } from 'react';
const App = () => {
const [userId, setUserId] = useState('');
const [userPw, setUserPw] = useState('');
const handleUserIdChange = (e) => {
setUserId(e.target.value);
}
const handleUserPwChange = (e) => {
setUserPw(e.target.value);
}
const handleLogin = async () => {
const res = await fetch('http://api.com/data',{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({userId: userId, userPw: userPw})
});
if(res.ok){
//성공 처리
} else {
//실패처리
}
}
return (
<div>
<div>
<label>id: </label>
<input value={userId} onChange={handleUserIdChange}/>
</div>
<div>
<label>pw: </label>
<input value={userPw} onChange={handleUserPwChange}/>
</div>
<div>
<button onClick={handleLogin}>로그인</button>
</div>
</div>
);
}
export default App;
Node.js와 브라우저를 위한 Promise 기반 HTTP비동기 통신 라이브러리
요청, 응답을 JSON형태로 자동변경
해당 라이브러리를 사용하기 위해서는 설치가 필요하다.
npm install axios
config.js 를 먼저 만들어 axios 객체를 생성해놓는다.
import axios from "axios";
export default axios.create({
baseURL: `http://api.com:3000/`,
headers: {
"Content-Type": "application/json",
},
timeout: 10000
});
그리고 api.js를 만들어 api호출을 관리하는 파일을 만든다.
import server from "./config.js";
export const getData = async ({param}) => {
return new Promise((resolve, reject) => {
server
.get('/data', {params: param})
.then((res) => {
resolve(res);
})
.catch((error) => {
console.log(error);
resolve(0);
});
});
}
그리고 실제 컴포넌트에서 사용
import React, { useState } from 'react'
import { getData } from '../api/api';
const AxiosTest = () => {
const [data, setData] = useState(null);
useEffect(() => {
const onLoad = async () => {
const res = await getData();
if(res){
//성공처리
console.log(res.data);
} else {
//실패처리
}
}
onLoad();
}, []);
return (
<div>{data && JSON.stringify(data)}</div>
)
}
export default AxiosTest;
React에서 비동기 질의(Query)를 도와주는 라이브러리
Fetching, Caching, 서버 데이터와의 동기화를 지원해주는 라이브러리이다.
기존에는 Fetching 코드를 작성 -> state생성 -> useEffect를 이용하여 데이터 fetching -> state에 저장 의 방법으로 사용되었는데
이 과정을 useQuery를 사용하면 다음과 같이 나타낼수 있다.
import { useQuery } from "@tanstack/react-query";
const getServerData = async () => {
const data = await fetch(
"http://api.com/data"
).then((response) => response.json());
return data;
};
export default function App() {
const { data } = useQuery(["data"], getServerData);
return <div>{JSON.stringify(data)}</div>;
}
React-query의 가장큰 장점은 캐싱이 가능하다는 것인다.
동일한 데이터의 재접근 속도를 높히는 방법이다.
const { data } = useQuery(['data', getServerData,{
staletime: 10 * 60 * 1000;
cashetime: 10 * 60 * 1000;
})
GET에는 useQuery가 사용되며
POST,PUT 등등에는 useMutation이 사용된다.
GraphQL은 facebook에서 개발한 기술로써 데이터 질의(Query + Schema) 언어 이다.
프론트에서 GraphQL 서버로 쿼리를 전송하고, 서버는 해당 쿼리를 해것하고 데이터를 반환한다.
이 때, 클라이언트가 요청한 필드만 반환되기 떄문에 Over Fetching이 줄어 효과적이 된다.
이번에는 API쪽의 코드 말고 React에서 GraphQL를 활용하는 방법만 정리해보도록 한다.
GraphQL를 사용하기 위해서 라이브러리 설치가 필요하다.
npm install @apollo/client graphql
app.js
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://api.com/graphql',
cache: new InMemoryCache()
});
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
);
컴포넌트 에서는 아래와같이 사용할 수 있다.
import React from 'react';
import { useQuery } from '@apollo/client';
import { gql } from 'graphql-tag';
const GET_USERS = gql`
query GetUsers {
users {
id
name
email
}
}
`;
function UserList() {
const { loading, error, data } = useQuery(GET_USERS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h2>User List</h2>
<ul>
{data.users.map(user => (
<li key={user.id}>
<strong>{user.name}</strong> - {user.email}
</li>
))}
</ul>
</div>
);
}
export default UserList;