Type something to search...

05 5 reactquery설정

1-TanStackQuery설치

1-1-패키지설치

  1. https://tanstack.com/query/latest/docs/framework/react/installation 이동
  2. 설치 npm i @tanstack/react-query

1-2-파일생성

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

  1. QueryPrivider 컴포넌트 작성
1
'use client';
2
import {QueryClient,QueryClientProvider} from '@tanstack/react-query';
3
import React, {ReactNode, useState} from 'react';
4
5
const QueryProvider = ({children}: {children: ReactNode}) => {
6
const [queryClient] = useState(
7
() =>
8
new QueryClient({
9
defaultOptions: {queries: {staleTime: Infinity}},
10
})
11
);
12
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
13
};
14
export default QueryProvider;

1-3-devtool 설치

  1. https://tanstack.com/query/latest/docs/framework/react/devtools#devtools
  2. npm i @tanstack/react-query-devtools
  3. 문서대로 따라한다. https://tanstack.com/query/latest/docs/framework/react/devtools#floating-mode
1
import { ReactQueryDevtools } from '@tanstack/react-query-devtools
1
<QueryClientProvider client={queryClient}>
2
{children}
3
** <ReactQueryDevtools initialIsOpen={false} />**
4
</QueryClientProvider>

1-4-Provider컴포넌트 적용

1-4-1-Layout.tsx

  1. next-with-supabase\app\layout.tsx
  2. ThemeProvider를 QueryPrivider 컴포넌트로 래핑한다

  1. 개발서버실행

2-사용자정보

2-1-Layout.tsx

  1. next-with-supabase\app\layout.tsx
  2. children을 main으로 래핑한다

2-2-Navbar.tsx

  1. next-with-supabase\components\Navbar.tsx 생성
1
import React from 'react';
2
3
const Navbar = () => {
4
return (
5
<>
6
<div>Navbar</div>
7
</>
8
);
9
};
10
export default Navbar;
  1. next-with-supabase\app\layout.tsx

children 전에 적용한다

  1. 확인

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

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

2-3-Profile.tsx

  1. next-with-supabase\components\Profile.tsx
1
import React from 'react';
2
import {Button} from './ui/button';
3
import Link from 'next/link';
4
5
const Profile = () => {
6
return (
7
<div>
8
<Link href="/auth">
9
<Button variant="outline">SignIn</Button>
10
</Link>
11
</div>
12
);
13
};
14
export default Profile;

2-4-Navbar.tsx

  1. next-with-supabase\components\Navbar.tsx
1
**import Link from 'next/link';**
2
import Profile from './Profile';
3
4
const Navbar = () => {
5
return (
6
<div className="flex justify-between items-center">
7
** <Link href="/">**
8
<h1 className="text-xl font-bold">Logo</h1>
9
** </Link>**
10
<Profile />
11
</div>
12
);
13
};
14
export default Navbar;
  1. 확인

2-5-사용자프로필

2-5-1-useUser.tsx

정보

💡 리액트 쿼리를 사용하여 사용자 정보를 가져온다

  1. next-with-supabase\app\hook\useUser.tsx
  2. 표시된 파일을 생성한다

  1. 코드작성
1
'use client';
2
import {useQuery} from '@tanstack/react-query';
3
import {createClient} from '@/lib/supabase/client';
4
5
export default function useUser() {
6
return useQuery({
7
queryKey: ['user'],
8
queryFn: async () => {
9
const supabase = createClient();
10
const {data} = await supabase.auth.getSession();
11
if (data.session?.user) {
12
const {data: user} = await supabase.from('profiles').select('*').eq('id', data.session.user.id);
13
return user;
14
}
15
},
16
});
17
}

2-5-2-수파베이스 타입 설치

수파베이스의 데이터베이스에서 사용중인 데이터들의 타입을 일일히 작성하기란 너무나도 까마득한 일이다. 수파베이스의 타입 생성기를 사용하면 자동으로 생성 된다.

  1. https://supabase.com/docs/guides/api/rest/generating-types 참조문서를 보면서 진행한다

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

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

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

  1. 성공

  1. 아래명령실행
1
npx supabase init

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

루트에 이미지와 같은 파일이 생성되었다.

정보

💡 만약 수파베이스 데이터베이스의 스키마나 테이블 등의 변경이 있을 경우 기존의 파일을 삭제한 후 8번을 다시 한다.

  1. 타입지정
  2. lib\supabase\server.ts
  3. lib\supabase\client.ts 두 파일에 타입을 연결해보자. 아래 영상을 참조.

루트 경로에 저장된 database.type 의 타입을 참조하고 있다. 11. 조회 결과 필터링

  1. app\hook\useUser.tsx 데이터베이스를 조회하는 메서드 위에 마우스를 호버하면 타입추론이 되는것을 볼수있다.

  1. 아래의 코드는 supabase의 특정 id 를 가진 데이터를 profiles 테이블에서 모두 조회하는 sql 쿼리이다.
1
supabase.from('profiles').select('*').eq('id', data.session.user.id)
  1. 동일한 아이디를 가진 사용자는 유일하므로 하나만 조회 하도록 한다.
1
...
2
if (data.session?.user) {
3
const {data: user} = await supabase.from('profiles').select('*').eq('id', data.session.user.id)**.single();**
4
return user;
5
}
6
...

2-5-3-조회결과가 없을경우

조회결과가 없을 경우에 대해 작성한다.

  1. app\hook\useUser.tsx
1
'use client';
2
import {useQuery} from '@tanstack/react-query';
3
import {createClient} from '@/lib/supabase/client';
4
5
**const initUser = {
6
created_at: '',
7
display_name: '',
8
email: '',
9
id: '',
10
image_url: '',
11
};
12
13
**...**
14
** return user;
15
} //end of if**
16
return initUser;
17
** },
18
});
19
}**
20
**

2-5-4-Profile.tsx

  1. useUser 훅 임포트
1
**'use client';**
2
import React from 'react';
3
import {Button} from './ui/button';
4
import Link from 'next/link';
5
**import useUser from '@/app/hook/useUser';**
6
7
const Profile = () => {
8
** const {isFetching, data} = useUser();**
9
return (
10
<div>
11
<Link href="/auth">
12
<Button variant="outline">SignIn</Button>
13
</Link>
14
</div>
15
);
16
};
17
export default Profile;

3-테이블권한설정

인증된 사용자는 데이터베이스의 읽기권한을 할당하고 개발화면에서 확인해보자

  1. 수파베이스 대시보드

  1. 데이터 연동 확인

4-Profile.tsx

4-1-유저이름표시하기

1
'use client';
2
import React from 'react';
3
import {Button} from './ui/button';
4
import Link from 'next/link';
5
import useUser from '@/app/hook/useUser';
6
7
const Profile = () => {
8
const {isFetching, data} = useUser();
9
** if (isFetching) {
10
return <></>;
11
}**
12
return (
13
<div>
14
** {!data?.id ? (**
15
<Link href="/auth">
16
<Button variant="outline">SignIn</Button>
17
</Link>
18
** ) : (
19
<h1>{data.display_name}</h1>
20
)}**
21
</div>
22
);
23
};
24
export default Profile;

4-2-아바타표시하기

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

  1. 확인

5-완료코드