5-reactquery설정
코드 블록의 Try it Yourself 버튼으로 직접 실행할 수 있다.
구문
1-TanStackQuery설치
1-1-패키지설치
- https://tanstack.com/query/latest/docs/framework/react/installation 이동
- 설치
npm i @tanstack/react-query

1-2-파일생성
- next-with-supabase\components\query-provider.tsx 파일생성

- QueryPrivider 컴포넌트 작성
'use client';
import {QueryClient,QueryClientProvider} from '@tanstack/react-query';
import React, {ReactNode, useState} from 'react';
const QueryProvider = ({children}: {children: ReactNode}) => {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {queries: {staleTime: Infinity}},
})
);
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
};
export default QueryProvider;
1-3-devtool 설치
- https://tanstack.com/query/latest/docs/framework/react/devtools#devtools
npm i @tanstack/react-query-devtools- 문서대로 따라한다. https://tanstack.com/query/latest/docs/framework/react/devtools#floating-mode
import { ReactQueryDevtools } from '@tanstack/react-query-devtools’
<QueryClientProvider client={queryClient}>
{children}
** <ReactQueryDevtools initialIsOpen={false} />**
</QueryClientProvider>
1-4-Provider컴포넌트 적용
1-4-1-Layout.tsx
- next-with-supabase\app\layout.tsx
- ThemeProvider를 QueryPrivider 컴포넌트로 래핑한다

- 개발서버실행

2-사용자정보
2-1-Layout.tsx
- next-with-supabase\app\layout.tsx
- children을 main으로 래핑한다

2-2-Navbar.tsx
- next-with-supabase\components\Navbar.tsx 생성
import React from 'react';
const Navbar = () => {
return (
<>
<div>Navbar</div>
</>
);
};
export default Navbar;
- next-with-supabase\app\layout.tsx

- 확인

- Navbar 이어서 코딩
const Navbar = () => {
//.flex.justify-between.items-center>h1.text-xl.font-bold
return (
<div className="flex justify-between items-center">
<h1 className="text-xl font-bold">Logo</h1>
</div>
)
};
export default Navbar;
- Profile 컴포넌트 추가후 생성


파일생성후 import 의 확장자 삭제

2-3-Profile.tsx
- next-with-supabase\components\Profile.tsx
import React from 'react';
import {Button} from './ui/button';
import Link from 'next/link';
const Profile = () => {
return (
<div>
<Link href="/auth">
<Button variant="outline">SignIn</Button>
</Link>
</div>
);
};
export default Profile;
2-4-Navbar.tsx
- next-with-supabase\components\Navbar.tsx
**import Link from 'next/link';**
import Profile from './Profile';
const Navbar = () => {
return (
<div className="flex justify-between items-center">
** <Link href="/">**
<h1 className="text-xl font-bold">Logo</h1>
** </Link>**
<Profile />
</div>
);
};
export default Navbar;
- 확인
2-5-사용자프로필
2-5-1-useUser.tsx
Info: 💡 리액트 쿼리를 사용하여 사용자 정보를 가져온다
- next-with-supabase\app\hook\useUser.tsx
- 표시된 파일을 생성한다

- 코드작성
'use client';
import {useQuery} from '@tanstack/react-query';
import {createClient} from '@/lib/supabase/client';
export default function useUser() {
return useQuery({
queryKey: ['user'],
queryFn: async () => {
const supabase = createClient();
const {data} = await supabase.auth.getSession();
if (data.session?.user) {
const {data: user} = await supabase.from('profiles').select('*').eq('id', data.session.user.id);
return user;
}
},
});
}
2-5-2-수파베이스 타입 설치
수파베이스의 데이터베이스에서 사용중인 데이터들의 타입을 일일히 작성하기란 너무나도 까마득한 일이다. 수파베이스의 타입 생성기를 사용하면 자동으로 생성 된다.
- https://supabase.com/docs/guides/api/rest/generating-types 참조문서를 보면서 진행한다

- 웹브라우저를 열고 수파베이스에 로그인한다.
npx supabase login실행- Ok to proceed 가 나오면 y 입력후 엔터

- 자동 로그인하려면 엔터 친다
- 웹브라우저가 열리고 인증키가 보이면 복사한다

- 터미널에 붙여넣고 엔터키 입력

- 성공

- 아래명령실행
npx supabase init

- $PROJECT_REF 에 본인의 ProjectID를 확인하여 변경한다
npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > database.types.ts



루트에 이미지와 같은 파일이 생성되었다.
Info: 💡 만약 수파베이스 데이터베이스의 스키마나 테이블 등의 변경이 있을 경우 기존의 파일을 삭제한 후 8번을 다시 한다.
- 타입지정
- lib\supabase\server.ts
- lib\supabase\client.ts 두 파일에 타입을 연결해보자. 아래 영상을 참조.
루트 경로에 저장된 database.type 의 타입을 참조하고 있다. 11. 조회 결과 필터링
- app\hook\useUser.tsx 데이터베이스를 조회하는 메서드 위에 마우스를 호버하면 타입추론이 되는것을 볼수있다.

- 아래의 코드는 supabase의 특정 id 를 가진 데이터를 profiles 테이블에서 모두 조회하는 sql 쿼리이다.
supabase.from('profiles').select('*').eq('id', data.session.user.id)
- 동일한 아이디를 가진 사용자는 유일하므로 하나만 조회 하도록 한다.
...
if (data.session?.user) {
const {data: user} = await supabase.from('profiles').select('*').eq('id', data.session.user.id)**.single();**
return user;
}
...
2-5-3-조회결과가 없을경우
조회결과가 없을 경우에 대해 작성한다.
- app\hook\useUser.tsx
'use client';
import {useQuery} from '@tanstack/react-query';
import {createClient} from '@/lib/supabase/client';
**const initUser = {
created_at: '',
display_name: '',
email: '',
id: '',
image_url: '',
};
**...**
** return user;
} //end of if**
return initUser;
** },
});
}**
**
2-5-4-Profile.tsx
- useUser 훅 임포트
**'use client';**
import React from 'react';
import {Button} from './ui/button';
import Link from 'next/link';
**import useUser from '@/app/hook/useUser';**
const Profile = () => {
** const {isFetching, data} = useUser();**
return (
<div>
<Link href="/auth">
<Button variant="outline">SignIn</Button>
</Link>
</div>
);
};
export default Profile;
3-테이블권한설정
인증된 사용자는 데이터베이스의 읽기권한을 할당하고 개발화면에서 확인해보자
- 수파베이스 대시보드


- 데이터 연동 확인
4-Profile.tsx
4-1-유저이름표시하기
'use client';
import React from 'react';
import {Button} from './ui/button';
import Link from 'next/link';
import useUser from '@/app/hook/useUser';
const Profile = () => {
const {isFetching, data} = useUser();
** if (isFetching) {
return <></>;
}**
return (
<div>
** {!data?.id ? (**
<Link href="/auth">
<Button variant="outline">SignIn</Button>
</Link>
** ) : (
<h1>{data.display_name}</h1>
)}**
</div>
);
};
export default Profile;

4-2-아바타표시하기
- h1을 삭제하고 NextJS의 Image 컴포넌트를 추가한다 components\Profile.tsx
...
import Image from 'next/image';
...
{!data?.id ? (
<Link href="/auth">
<Button variant="outline">SignIn</Button>
</Link>
) : (
** <Image src={data.image_url || ''} alt={data.display_name || ''} width={50} height={50} className="rounded-full" />**
)}
</div>
- 이미지 패스 추가 테이블의 image_url의 도메인 부분을 next설정 파일에 작성한다 next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'avatars.githubusercontent.com',
},
{
protocol: 'https',
hostname: 'lh3.googleusercontent.com',
},
],
},
};
export default nextConfig;

- 확인
