[React.js] 리액트의 네트워크 상태 관리 훅, SWR
2024. 1. 16. 16:41ㆍ프론트엔드/React.js
반응형
SWR
- 네트워크 상태 관리 툴
- React hooks for Data Fetching
- made by vercel
- stale-while-revalidate
- SWR is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.
- 빠르게 화면에 보이는 캐시된 데이터를 제공하고, 동시에 백그라운드에서 데이터를 다시 가져와서 UI를 새로 고치는 방식
- SWR에서 "캐시"는 메모리 내에 저장된 데이터의 일시적인 복사본을 의미한다
- 사용자 경험을 향상시키고, 데이터의 최신 상태를 유지 가능
const { data, isLoading, error } = useSWR("/api/me");
fetcher 전역 설정
// SWRConfigContext.tsx
"use client";
import { SWRConfig } from "swr";
type Props = {
children: React.ReactNode;
};
export default function SWRConfigContext({ children }: Props) {
return (
<SWRConfig
value={{
fetcher: (url: string) => fetch(url).then((res) => res.json()),
}}
>
{children}
</SWRConfig>
);
}
<SWRConfigContext>{children}</SWRConfigContext>
useSWR()
const { data, isLoading, error } = useSWR<DetailUser>("/api/me");
- 리액트 쿼리와 흡사
useSWR('경로')
를 사용하여 데이터를 가져옴- 라이브러리 자체적으로 데이터를 fetch
fetcher
옵션을 이용하여 fetch된 데이터를 JSON으로 반환 설정- 요청이 시작되면
isLoading
값이true
로 설정 - 요청 중 발생한 에러는
error
변수에 저장 - 데이터를 모두 받아와서 JSON으로 변환이 완료되면 이 데이터는
data
변수로 반환
GROQ
- Sanity Query Language
- Graph-Relational Object Queries
- text matching, order, slice, join, 데이터 가공 등이 가능함
쿼리 Query
- 쿼리 : 데이터베이스나 정보 시스템에서 정보를 요청하거나 검색하기 위해 사용되는 명령문이나 요청
-- 사용자 테이블에서 이름과 이메일 가져오기
SELECT name, email FROM users;
-- 제품 테이블에서 가격이 50 이상인 제품 가져오기
-- 모든 컬럼 선택
SELECT * FROM products WHERE price >= 50;
-- 특정 컬럼만 선택
SELECT name, price FROM products WHERE price >= 50;
# GraphQL에서 사용자 이름과 이메일 가져오기
query {
users {
name
email
}
}
# GraphQL에서 가격이 50 이상인 제품 가져오기
query {
products(where: { price_gte: 50 }) {
name
price
}
}
// GROQ에서 사용자 이름과 이메일 가져오기
*[_type == 'user'] {
name,
email
}
// GROQ에서 가격이 50 이상인 제품 가져오기
// 모든 컬럼 선택
*[_type == 'product' && price >= 50]
// 특정 컬럼 선택
*[_type == 'product' && price >= 50] {
name,
price
}
- 참고 : 필요한 필드만을 명시적으로 선택하여 가져오는 것이 일반적이다.
mutate
mutate
함수를 사용하면, UI에 대한 실시간 업데이트가 필요하지 않은 상황에서도 데이터 갱신을 효과적으로 처리할 수 있다.- 캐시된 데이터를 업데이트하고, 필요에 따라 컴포넌트를 리렌더링할 수 있다.
- Global Mutate : 어떤 키든지 변경할 수 있음
- Bound Mutate : 해당 SWR 훅의 데이터만 변경할 수 있음
Global Mutate
import { useSWRConfig } from "swr"
function App() {
const { mutate } = useSWRConfig() //-> global mutate
mutate(key, data, options)
}
Bound mutate
import useSWR from 'swr';
function Profile() {
const { data, mutate } = useSWR('/api/user', fetcher); //-> bound mutate
return (
<div>
<h1>My name is {data.name}.</h1>
<button onClick={async () => {
const newName = data.name.toUpperCase();
// API에 데이터를 업데이트하는 요청을 보냄
await requestUpdateUsername(newName);
// 로컬 데이터를 즉시 업데이트하고 다시 유효성 검사 (재검색)
mutate({ ...data, name: newName }); // 현재 키(`/api/user`)에 바인딩되어 있으며, 키를 명시적으로 지정할 필요 없이 현재 키와 새로운 데이터로 캐시를 갱신
}}>Uppercase my name!</button>
</div>
);
}
Revalidation
mutate
함수 호출:mutate
함수는 데이터를 업데이트하고, 기본적으로 해당 데이터를 서버에서 다시 가져와서 UI를 갱신- 만약
mutate
를 호출할 때 데이터를 전달하지 않는다면, 이는 해당 데이터가 만료된 것으로 표시
- 재검증 (Revalidation):
- 만료된 데이터가 표시되면 SWR는 리소스에 대한 재검증 수행
- 이는 기본적으로 서버에 새로운 데이터를 요청하고, 캐시를 갱신하여 최신 데이터로 UI를 업데이트하는 과정을 포함한다.
- SWR는 백그라운드에서 비동기적으로 데이터를 갱신하고, UI를 업데이트한다.
import useSWR, { useSWRConfig } from 'swr'
function App () {
const { mutate } = useSWRConfig()
return (
<div>
<Profile />
<button onClick={() => {
// set the cookie as expired
document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
// tell all SWRs with this key to revalidate
mutate('/api/user')
}}>
Logout
</button>
</div>
)
}
Options
optimisticData
:- 클라이언트 캐시를 즉시 업데이트하는 데 사용되는 데이터
- 즉각적으로 UI가 업데이트될 수 있도록 미리 만들어둔 데이터를 전달할 수 있음
- 기본값:
undefined
(낙관적인 업데이트를 사용하지 않음)
revalidate
:- 비동기 업데이트가 완료된 후에 캐시를 다시 유효성 검사 여부를 결정
true
로 설정하면 업데이트가 완료된 후에 서버에서 새로운 데이터를 가져와서 UI를 갱신함.- 기본값:
true
populateCache
:- mutate의 결과값을 기존 데이터에 덮어쓸 지 말지를 결정
- (정확히는 캐시 기록 여부 결정)
- 기본값:
true
rollbackOnError
:- mutate 진행 중 오류 발생 시, 캐시 롤백 여부 결정
- 기본값:
true
반응형
'프론트엔드 > React.js' 카테고리의 다른 글
[React] 이벤트 핸들링/ 함수를 바인딩(전달)하는 올바른 방법 feat. 이벤트 객체, 함수 커링 (0) | 2023.02.12 |
---|---|
[React] Context API (0) | 2022.09.26 |
[React] 이벤트 전달, onClick={} 에서 함수에 () 붙고 안 붙고 차이 (0) | 2022.09.04 |
[React] 리액트 라우팅, React Router Dom ( useParams, useSearchParams, useNavigate ) (0) | 2022.08.16 |
[React] useReducer 이해하기 (0) | 2022.08.08 |