supabase 로그인 유저 정보 가져오기

임보라·2024년 10월 25일

Supabase

목록 보기
2/2

로그인 유저정보를 가져오는 방법으로 한 파일에 모두 불러오거나 파일분리로 하는법 두 가지를 모두 써보았는데 보기에는 파일분리가 더 깔끔해보인다.
텐스텍쿼리로 값을 연결지어서 쓰는법까지 같이 익혔다.
상황에 따라 맞는 방법을 쓰겠지만 난 이번에 2번째방법을 쓸거같다.

1번째 방법 - 한 컴포넌트에 getUser

  1. userId 상태값 저장할 state 생성
  2. useEffect 로 browserClient.auth.getUser() 감싸주기
    ->처음 랜더링됬을때 유저값 가져오기
    ->browserClient.auth.getUser() : supabase에서 로그인된유저값 가져오는거
  3. setUserId(데이터) 넣어서 userId값에 저장되도록
  4. mutaion실행하는 이벤트함수(삭제클릭,추가클릭이벤트)에 인자로 userId 넘겨주기
  5. supabase에 추가,삭제하는 뮤테이션함수(비동기)에서 인자로 userId 받기

- StampActive 컴포넌트

'use client';
...
//뮤테이션 함수 만들기(수파베이스 값 추가)
const addStampList = async ({
  ...
  userId
}) => {
  const { data, error } = await browserClient.from('stamp').insert({
    user_id: userId,
    ...
  });
  if (error) console.log('error', error);
  return data;
};

//뮤테이션 함수 만들기(수파베이스 값 삭제)
const deleteStampList = async ({ address, userId }) => {
  const { data, error } = await browserClient.from('stamp').delete().eq('address', address).eq('user_id', userId);
  if (error) console.error('삭제중 오류 발생:', error);
  return data;
};


const StampActive = ({ address }: StampActivePropsType) => {
  const queryClient = useQueryClient();
  const router = useRouter();

  const [userId, setUserId] = useState<string | null>(null);

  useEffect(() => {
    const fetchUser = async () => {
      const { data, error } = await browserClient.auth.getUser();
      if (error || !data?.user) {
        router.push('/logIn');
      } else {
        setUserId(data.user.id);
      }
    };
    fetchUser();
  }, [router]);

  //useMutation(삭제)
  const StampDeleteMutation = useMutation({
    mutationFn: deleteStampList,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['nowStamp'] });
    }
  });
  //useMutation(추가)
  const StampAddMutation = useMutation({
    mutationFn: addStampList,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['nowStamp'] });
    }
  });

  //mutate 추가이벤트(방문안한 상태에서 누르면)
  const onClickVisitedAdd = (address: string, regionName: string) => {
    const visitedConfirmed = window.confirm('스탬프를 찍겠습니까?');
    if (visitedConfirmed) {
      StampAddMutation.mutate({ address, regionName, userId });
      console.log('스탬프가 찍혔습니다.');
    } else {
      return;
    }
  };
  //mutate 삭제이벤트(방문한 상태에서 누르면)
  const onClickVisitedCencle = (address: string) => {
    const cancelConfirmed = window.confirm('스탬프를 취소하시겠습니까?');
    if (cancelConfirmed) {
      StampDeleteMutation.mutate({ address, userId });
      console.log('스탬프가 취소되었습니다.');
    } else {
      return;
    }
  };

  //useQuery
  const {
    data: stampList,
    isLoading,
    error
  } = useQuery({
    queryKey: ['nowStamp', address.address_name], //고유키값
    queryFn: () => fetchStampList(address.address_name) // 주소를 인자로 넘김
  });
  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Failed to load</div>;
  console.log('address', address);
  const REGIONimageUrl = STAMPIMG_REGION_NAME[address.region_1depth_name];
...

2번째 방법 - 파일분리 ,함수 활용

  1. 패치비동기함수(.auth.getUser()) 파일분리 - fetchUser.ts
  2. 사용할 컴포넌트에서 import로 fetchUser.ts 불러오기
  3. userId state 생성
  4. useEffect로 처음 랜더링됬을때 패치함수 호출
  5. setUserId(데이터) 넣어서 userId값에 저장되도록
  6. useQuery에서 쿼리함수에 userId 인자로 넘겨주기
  7. 쿼리함수에서 인자로 userId 받아서 사용하기

- fetchUser.ts

import browserClient from '@/utils/supabase/client';

//로그인 유저 아이디 가져오기
export const fetchUser = async () => {
  const { data, error } = await browserClient.auth.getUser();
  if (error || !data?.user) {
    console.log('error');
  }
  return data.user?.id;
};
fetchUser();

- fetchStampList 컴포넌트

'use client';

import React, { useEffect, useState } from 'react';
import StampItem from '@/components/stamp/StampItem';
import { useQuery } from '@tanstack/react-query';
import browserClient from '@/utils/supabase/client';
import { fetchUser } from '@/utils/fetchUser';

//로그인유저의 스템프 항목 전부 가져오기
const fetchStampList = async (userId: string) => {
  const { data, error } = await browserClient.from('stamp').select('*').eq('userid', userId).eq('visited', true);
  if (error) console.error('가져오기 오류:', error.message);
  return data;
};

const StampList = () => {
  const [userId, setUserId] = useState<string | null>(null);

  useEffect(() => {
    const checkUser = async () => {
      const user = await fetchUser();
      if (!user) return;
      else setUserId(user);
    };
    checkUser();
  }, []);

  const {
    data: stampList,
    isLoading,
    error
  } = useQuery({
    queryKey: ['stamp'], //고유키
    queryFn: () => fetchStampList(userId!) //!null이 아님 보장
  });
  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Failed to load</div>;

  return (
    <ul className="grid grid-cols-2 gap-4">{stampList?.map((stamp) => <StampItem key={stamp.id} stamp={stamp} />)}</ul>
  );
};

export default StampList;

레퍼런스
supabase 공식문서

0개의 댓글