[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에 대한 실시간 업데이트가 필요하지 않은 상황에서도 데이터 갱신을 효과적으로 처리할 수 있다.
  • 캐시된 데이터를 업데이트하고, 필요에 따라 컴포넌트를 리렌더링할 수 있다.
  1. Global Mutate : 어떤 키든지 변경할 수 있음
  2. 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

  1. mutate 함수 호출:
    • mutate 함수는 데이터를 업데이트하고, 기본적으로 해당 데이터를 서버에서 다시 가져와서 UI를 갱신
    • 만약 mutate를 호출할 때 데이터를 전달하지 않는다면, 이는 해당 데이터가 만료된 것으로 표시
  2. 재검증 (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

  1. optimisticData:
    • 클라이언트 캐시를 즉시 업데이트하는 데 사용되는 데이터
    • 즉각적으로 UI가 업데이트될 수 있도록 미리 만들어둔 데이터를 전달할 수 있음
    • 기본값: undefined (낙관적인 업데이트를 사용하지 않음)
  2. revalidate:
    • 비동기 업데이트가 완료된 후에 캐시를 다시 유효성 검사 여부를 결정
    • true로 설정하면 업데이트가 완료된 후에 서버에서 새로운 데이터를 가져와서 UI를 갱신함.
    • 기본값: true
  3. populateCache:
    • mutate의 결과값을 기존 데이터에 덮어쓸 지 말지를 결정
    • (정확히는 캐시 기록 여부 결정)
    • 기본값: true
  4. rollbackOnError:
    • mutate 진행 중 오류 발생 시, 캐시 롤백 여부 결정
    • 기본값: true

https://swr.vercel.app/docs/mutation

반응형