본문 바로가기

Supabase 셋업 이후 TanStack Query 커스텀 훅으로 fetch 전역 공유하기

codeConnection 2024. 6. 17.

주의

Supabase 라이브러리에서 제공하는 내장 함수가 더 좋다.

Supabase는 기본적으로 REST API를 지원하기 때문에 아래의 방식이 잘 작동되지만 굳이 Axios Fetch를 보내는 것을 권장하진 않는다.

준비물

  • Supabase Project URL
  • Anon-key(Public)
  • 라이브러리: axios, TanStack Query

파일 트리

node_modules
public
src
	assets
    components
    	api
    		axiosInstance.js
    hooks
		usePlaces.js
    App.jsx
    main.jsx
index.html
package.json
.env
.gitignore
...

파일트리는 위 내용이 전부가 아니고, 기본 파일은 똑같다. 아래 두 개의 파일은 새로 생성한다.

  • src/components/api/axiosInstance.js (자유 작명)
  • src/componets/hooks/usePlaces.js (api 명칭에 따라 커스텀 훅 자유 작명)

방법

패키지 설치

yarn add @tanstack/react-query axios

TanStack Query Provider 설정

// main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
import './index.css';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; // <-- import

const queryClient = new QueryClient();

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}> // {/* Provider로 감싸기 */}
      <App />
    </QueryClientProvider>
  </React.StrictMode>,
);

환경변수 설정

// src/.env

VITE_SUPABASE_URL=프로젝트 URL
VITE_SUPABASE_KEY=퍼블릭 키
// src/.gitignore

.env

Axios Instance 설정

// src/api/axiosInstance.js

import axios from 'axios';

const axiosInstance = axios.create({
  baseURL: import.meta.env.VITE_SUPABASE_URL,
  headers: {
    apikey: import.meta.env.VITE_SUPABASE_KEY,
  },
});

export default axiosInstance;

TanStack Query 커스텀 훅 작성

// src/hooks/usePlaces.js

import { useQuery } from '@tanstack/react-query';
import axiosInstance from '../components/api/axiosInstance';

const fetchPlaces = async () => {
    const response = await axiosInstance.get('/rest/v1/places', {
        headers: {
            'Content-Type': 'application/json',
            'apikey': import.meta.env.VITE_SUPABASE_KEY,
        },
    });
    return response.data;
};

const usePlaces = () => {

    return useQuery({
        queryKey: ['places'],
        queryFn: fetchPlaces,
    });
};

export default usePlaces;
  • 본인의 데이터 테이블 이름이 places라서 저렇게 설정함.
  • fetchPlaces라는 함수로 axiosInstance에 접근하여 get 요청을 보내는 함수 작성 후
  • usePlaces라는 커스텀 훅을 제작함. 이 커스텀 유틸 함수를 export 한 뒤 필요한 곳에서 import 하여 사용하면 됨.

다른 컴포넌트에서 커스텀 훅 사용하기

// 커스텀 훅 import
import usePlaces from './hooks/usePlaces';

function App() {

  // 커스텀 훅에서 필요한 정보 구조 분해 할당으로 꺼내옴.
  const { data: places, isPending, isError, error } = usePlaces();

  if (isPending) return <div>로딩 중입니다...</div>;
  if (isError) return <div>에러가 발생했습니다: {error.message}</div>;

  // data 또는 바꾼 이름 places로 바로 꺼내와서 사용 가능
  return (
    <>
      <h1>API 호출 테스트</h1>
      <TestDiv>
        {places && places.map((place) => (
          <TestItemDiv key={place.post_id}>
            <p>행사명 : {place.name}</p>
            <p>행사 시작일 : {place.st_date}일 {place.st_time}분 시작</p>
            <p>행사 종료일 : {place.ed_date}일 {place.ed_time}분 종료</p>
            <p>행사 종류 : {place.category}</p>
            <p>행사장 주소 : {place.address}</p>
            <p>참가비 : {place.pricing} 원</p>
            <p>행사 상세내용 : {place.description}</p>
            <p>행사 이미지 : <img src={place.image} style={{ width: '200px' }} /></p>
          </TestItemDiv>
        ))}
      </TestDiv>
    </>
  );
}

 

댓글