Voyage_dev
항해하는 개발자
Voyage_dev
전체 방문자
오늘
어제
  • All (158)
    • Front-End (102)
      • HTML & CSS (7)
      • JavaScript (13)
      • Web & 표준 & ETC (15)
      • React (17)
      • Next (13)
      • TypeScript (6)
      • Zustand (1)
      • AWS (4)
      • Redux (1)
      • MobX (9)
      • GraphQL (1)
      • Flutter (15)
    • 알고리즘 (12)
      • Java (11)
      • JavaScript (1)
    • Git (1)
    • Project (2)
      • 개인 (1)
      • 팀 (1)
    • Books (30)
      • 누구나 자료구조와 알고리즘 (20)
      • Do It 타입스크립트 프로그래밍 (9)
    • 자료구조 (6)
    • 취업 (1)
    • 항해플러스 (1)
      • 1주 (1)

블로그 메뉴

  • 👨🏻‍💻 Github
  • 💻 Rss 블로그
  • 🏊‍♂️ Resume
  • 🗂️ Portfolio

인기 글

최근 댓글

hELLO · Designed By 정상우.
Voyage_dev

항해하는 개발자

useSWR로 API 호출 재사용성 높이기
Front-End/Next

useSWR로 API 호출 재사용성 높이기

2023. 3. 13. 01:34

SWR란?

React-Query와 비슷한 개념으로 서버에서 데이터를 가져와서 사용하는 Vercel이 개발한 React hooks이다.
더 자세한 개념이랑 사용 방법은 전 글을 참고하자

  • https://voyage-dev.tistory.com/158

이번에는 SWR hooks로 데이터를 프리렌더링 하며 axios를 이용해 호출 재사용성 높이는 방법을 알아보자.

 

useSWR 함수

SWR 함수는 기본적으로 1개의 인자를 필수로 받는다.

  • key : fetcher 함수에게 전달되는 인자 ⇒ 보통 URL을 넣는다
  • fetcher : 데이터를 실질적으로 fetch하는 함수이다
  • option : revalidate , mutate, initialData 등 옵션을 넣어줄 수 있다

사용 순서는 다음과 같다.

  • fetcher를 만든다. 여기서 불러오는 데이터의 url을 지정하고 불러오게 된다.
import axios from "axios";

export const fetcher = (url: string) => axios.get(url);
  • 데이터를 요청할 때 사용할 key값을 fetcher와 함께 넘겨준다.
const { data, error, isValidating, mutate } = useSWR(key, fetcher, options)

재사용성 높이기

import type { AppProps } from "next/app";
import { ThemeProvider } from "styled-components";
import GlobalStyles from "@styles/_GlobalStyles";
import { color, mixins } from "@styles/_theme";
import Layout from "@components/Common/Layout";
import { SWRConfig } from "swr";
import { request } from "lib/axios-utils";
import Head from "next/head";
import "@fortawesome/fontawesome-svg-core/styles.css";

export default function App({ Component, pageProps }: AppProps) {
  return (
      <ThemeProvider theme={{ ...color, ...mixins }}>
        <GlobalStyles />
        <SWRConfig value={{ fetcher: request }}>
          <Layout>
            <Component {...pageProps} />
          </Layout>
        </SWRConfig>
      </ThemeProvider>

  );
}

app.tsx에서 SWRConfig로 fetcher를 감싸주므로 SWR을 전역적으로 사용하는 모든 곳에서 fetcher 함수를 넣어주지 않아도 된다.

const SellerPage = ({ seller, qna }: Props) => {

  const { data: sellerData, error } = useSWR(`?q=sellers`, {
    fallbackData: seller,
  });
})

이런식으로 useSWR에 key 값만 넣어놔도 알아서 fetcher 함수가 실행된다. 여기서 fallbackData는 미리 pre-rendering 된 데이터를 넣어주므로 인해 아직 데이터가 도착하지 않았을 때 보여줄 내용을 미리 넣어두는 것이라고 할 수 있다.

 

아까 SWRConfig fetcher에 request 함수를 설정했다.

// request
import axios from "axios";

const client = axios.create({
  baseURL: "/api",
});

export const request = async ({ ...options }) => {
  const queryParam = Object.values(options).join("");

  client.defaults.headers.common.Authorization = "Bearer token";
  const onSuccess = (response: any) => response;
  const onError = (error: Error) => {
    return error;
  };

  return client(queryParam).then(onSuccess).catch(onError);
};

여기서 queryParam으로 한 번 처리한 이유는 key값이 split된 형태인 “?”, “q”, ”=” ”s”, ”e”, ”l”, ”l”, ”e”, ”r”, ”s” 로 들어오기 때문에 한 번 처리해서 원하는 api 위치로 보내기 위함이다.

또 이렇게 q= 형태로 보내면 next는 req.query.q로 값을 받을 수 있기 때문에 기본적인 base url이 같고 api 뒤 값만 다르다면 api 폴더를 하나로 관리할 수 있다.

import axios from "axios";
import { BASE_URL } from "config";
import type { NextApiRequest, NextApiResponse } from "next";

const client = axios.create({
  baseURL: BASE_URL,
  headers: {
    Accept: "application/json",
  },
  withCredentials: true,
});

const getData = async (req: NextApiRequest, res: NextApiResponse) => {
  const query = req.query.q; // 이 부분!

  const { data } = await client.get(`/api/${query}?populate=*`);

  return res.status(200).json(data.data);
};

export default getData;

요청하는 api값이 다르다면 요청하는 폴더를 만들어야 되지만, 뒤에 값만 다르다면 이렇게 하나로 관리할 수 있기 때문에 불필요한 파일을 작성할 필요가 없다.

 

참고로 pre-rendering 시에는 요청 보낼 주소를 다 적어야 한다. 그 이유는 prefetch되는 서버에서는 기본적으로 모든 URL이 있어야 해당 데이터를 요청 및 받을 수가 있다.

import SellerPage from "@components/Pages/Seller";
import { Props } from "@components/Pages/Seller/types";
import { BASE_URL } from "config";
import { fetcher } from "lib/fetcher";
import { GetStaticProps } from "next";
import React from "react";

const Seller = ({ seller }: Props) => {
  return <SellerPage seller={seller} />;
};

export default Seller;

// pre-rendering
// 서버에서 데이터 요청 받은 후 빌드시에 클라이언트로 보내주는 코드이다
export const getStaticProps: GetStaticProps = async () => {
  const seller = await fetcher(`${BASE_URL}/api/sellers`).then(
    data => data.data
  );

  return {
    props: {
      seller,
    },
  };
};

 

출처 : 아래의 사이트들을 보면서 큰 공부 하였습니다

  • https://velog.io/@soryeongk/SWRBasic
  • https://velog.io/@denmark-banana/Nextjs-PreRendering-useSWR
  • https://swr.vercel.app/docs/with-nextjs

'Front-End > Next' 카테고리의 다른 글

Next.js 프레임워크 라우팅 구조와 데이터 패칭  (0) 2024.08.04
Next.js 프레임워크  (0) 2024.08.02
[Next.js] React-Query로 쿼리 캐싱한 데이터 가져오기  (3) 2022.11.26
[Next.js] Serverless + Github Actions로 Vercel 배포 및 자동화 작업  (0) 2022.11.09
[Next.js] 정적 사이트에 다크 모드 구현하기  (0) 2022.11.06
    'Front-End/Next' 카테고리의 다른 글
    • Next.js 프레임워크 라우팅 구조와 데이터 패칭
    • Next.js 프레임워크
    • [Next.js] React-Query로 쿼리 캐싱한 데이터 가져오기
    • [Next.js] Serverless + Github Actions로 Vercel 배포 및 자동화 작업
    Voyage_dev
    Voyage_dev

    티스토리툴바