1. React-Query란
React Query는 React 애플리케이션에서 데이터 상태 및 비동기 데이터 관리를 용이하게 해주는 JavaScript 라이브러리이다.
React Query의 역할은 서버로부터 데이터를 가져오고, 저장하고, 동기화하며, 상태를 관리하는데 도움을 준다.
- 공식문서 주소: https://tanstack.com/query/v3
* 상태관리 라이브러리 중 React Query를 사용하는 이유 :
비슷한 상태관리 라이브러리로는 redux
, recoil
이 있다.
대부분의 기존 상태관리 라이브러리는 비동기 또는 서버상태 작업에 적합하지 않고 클라이언트 상태와 서버 상태를 함께 담아두고 있다.
적합하지않은 이유는 서버상태가 완전히 다르기 때문이다
하지만 react-query를 사용해 서버 상태를 관리한다면 클라이언트 상태를 분리하여 관리할 수 있기 때문에 직관적이고 효율적인 관리가 가능하다.
서버상태 :
1. 통제하지 않은 위치에 원격으로 유지 된다.
2. 데이터를 가져오기 및 업데이트를 위한 비동기 api가 필요
3. 공유사용자 모르게 다른사람이 변경 할 수 있음
4. 업데이트를 하지않으면 잠재적으로 오래된 데이터가 될수 있다.
이러한 상태때문에 발생될 수 있는 문제들을 react-query에서 지원하는 다양한 옵션들을 사용하여 캐싱, 에러처리, suspense, refresh, data fetching 조건 설정 등등의 기능들을 선언적이고 간편하게 이용할 수 있도록 도와준다.
2. React-Query 구조
설명하기 앞서 기본적인 기능과 구조에 대해 설명하고 실제로 사용해본 기능들 위주로 작성되었다.
2-1. 기본 구조
const { data, error, isLoading, status } = useQuery(
["login", isLogin], // key 설정
async () => { // 콜백함수
if (isLoading) {
ex) return <span>Loading...</span>
}
if (isError) {
ex) return <span>Error: {error.message}</span>
}
const response = await fetch("/api/getUserList")
const data = await response.json() // API 응답 데이터 처리
if (isLogin) {
setUserName(data.user[0].user_name)
} else {
setUserName(false)
}
return data // 응답 데이터 반환
}
)
위 코드를 통해 알아보면 useQuery로 react hook과 유사한 구조로 사용하고 있으며 두 가지의 인자값을 가지게 됩니다.
id ( ["login", isLogin] )와 callback함수 두가지를 받는데 id는 서버 상태를 관리하기 위해 React-Query는 캐싱을 하게 되는데 이때 캐싱시키고 다시 불러오기 위한 고유한 키값을 가지게 됩니다.
2-2. key값의 형태
1) string
useQuery('todos', ...) // queryKey === ['todos']
2) Array Keys
useQuery(['todo', 5], ...)
// queryKey === ['todo', 5]
* 동일한 키로 작동 되는 예제
- 해당아래의 코드는 동일한 key로 인식된다.
useQuery(['todos', { status, page }], ...)
useQuery(['todos', { page, status }], ...)
2-3. 콜백함수
fetch함수를 콜백으로 받게 되는데 이 함수를 실행시킨 값을 캐싱해서 저장하는 함수를 사용한다.
ex) () => fetchTodoList(event), fetchTodoList ,
async () => {
const response = await fetch("/api/getUserList")
const data = await response.json() // API 응답 데이터 처리
}
3. React-Query : ReactQueryDevtools 라이브러리
만약 실제로 동작하는지 궁금하다면 간단한 설정을 사용해볼 수있는데 ReactQueryDevtools
를 import하여 확인가능 하다
import React, { useState } from 'react';
import styled, { createGlobalStyle } from "styled-components";
import Router from './Router';
import { ReactQueryDevtools } from 'react-query/devtools'
import { GlobalStyle } from './styles/global-styles';
function App() {
return (
<>
<GlobalStyle/>
<Router/>
<ReactQueryDevtools initialIsOpen={true}/>
</>
);
}
export default App;
⭐ 4. React-Query : GET, POST Api 통신 방법
4-1. get
const { data, error, isLoading, status } = useQuery(
["login", isLogin],
async () => {
const response = await fetch("/api/getUserList")
const data = await response.json() // API 응답 데이터 처리
if (isLogin) {
setUserName(data.user[0].user_name)
setUserRange(data.user[0].auth_level)
} else {
setUserName(false)
setUserRange(1)
}
return data // 응답 데이터 반환
}
4-2. 클릭이벤트 발생시 post를 통한 api통신
import axios from "axios"
import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query"
export default function App({setSelect, select}) {
// react-query
const queryClient = useQueryClient()
// react-query 이벤트 발생시 데이터 업데이트
const mutation = useMutation({
mutationFn: (data) => {
return data
},
onSuccess: (data) => {
queryClient.invalidateQueries(["Select"]) // 데이터 초기화 기능
queryClient.setQueryData(["Select"], data) //Select 키의 쿼리 데이터 생성 및 업데이트
setSelect(data) // Index.js에 쿼리데이터 업데이트를 반영하고자 재 렌더링을 위한 props업데이트
}
})
// 클릭 이벤트
const onSelect = async (keys, info) => {
let inputData = [
keys: keys,
info: info
]
await axios
.post("/api주소", inputData)
.then((res) => {
let resultData = res.data
mutation.mutate(resultData) //업데이트
})
.catch((e) => {})
}
return (
<>
<button onClick={() => {onSelect(keys, info)}>click</button>
</>
)
}
4-3. 데이터 가져오기 및 업데이트
import App from "./App"
import { useQueryClient, useQuery } from "@tanstack/react-query"
export default function Index() {
const queryClient = useQueryClient()
const [select, setSelect] = useState("") //재 렌더링을 위한 props
const RQResult = queryClient.getQueryData(["Select"]) // 데이터 가져오기
const [result, setResult] = useState([])
// RQResult 가 업데이트 될때 마다 새 값을 equip에 넣기
useEffect(() => {
if (RQResult) {
console.log(RQResult)
setResult(RQResult)
}
}, [RQResult])
console.log(result, "result")
return (
<>
<App setSelect={setSelect} select={select} />
<div></div>
</>
)
}
'FrontEnd_Study > REACT' 카테고리의 다른 글
useLocation()의 사용이유와 window.location과 차이점 (0) | 2024.06.20 |
---|---|
React.lazy 와 Suspense 사용하기 (0) | 2023.05.11 |
리액트(React) 실행 및 관련 파일 정리 (0) | 2022.02.16 |
리액트(React)란?(개념정리) (0) | 2022.02.16 |
Virtual DOM이란? (+작동원리) (0) | 2022.02.16 |