๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

Project: ๐Ÿšฉcodefolio - recoil, supabase Auth

ยท ์•ฝ 2๋ถ„
Seung hyo, Lee
Front End Engineer @ Assistfit
๐ŸŽฏ๋ชฉ์ 

Supabase Auth - ๋กœ๊ทธ์•„์›ƒ, ๋กœ๊ทธ์ธ ์ƒํƒœ(recoil)


1. recoil + supabase getSession()โ€‹

import { atom } from "recoil";

const userLoginCheck = atom<boolean>({
key: "userLoginCheck",
default: false,
});

export default userLoginCheck;

์ „์—ญ ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ํ”„๋กœ์ ํŠธ์—์„œ recoil์„ ๋„์ž…ํ–ˆ๋‹ค. ์‚ฌ์šฉ๋ฒ•์€ ๋‹ค๋ฅธ ์ „์—ญ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋น„ํ•ด ๋„ˆ๋ฌด ๊ฐ„๋‹จํ•˜๋‹ค.

atom์„ importํ•ด์ค€ ํ›„ useState์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋กœ ์ธํ•ด default์˜ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ฃผ๊ณ , atom์— ์ „๋‹ฌ๋˜๋Š” object๋Š” key์™€ value๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ key์— ์„ ์–ธํ•  text์™€ default์—๋Š” ๊ธฐ๋ณธ๊ฐ’ ์ฆ‰, ์ด๋‹ˆ์…œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด๊ฐ€๋ฉด ๋œ๋‹ค.

import { useSetRecoilState } from "recoil";
import { userLoginCheck } from "@/lib/recoil";

const setUserLogin = useSetRecoilState(userLoginCheck);

const onLogoutButtonClick = async () => {
const res = await supabase.auth.signOut();
setUserLogin(false);
if (res.error) {
console.log("๋กœ๊ทธ์•„์›ƒ ์—๋Ÿฌ", res.error);
return;
throw new Error(res.error.message);
}
router.push("/");
return router.push("/");
};

์œ„ ์ฝ”๋“œ์—์„œ๋Š” ์ฒซ๋ฒˆ์งธ๋กœ recoil ๋ฉ”์„œ๋“œ๋ฅผ importํ•ด ์ฃผ๊ณ  ์•„๊นŒ ๋งŒ๋“ค์–ด๋†“์€ atom์„ ์–ธ ํ•จ์ˆ˜๋„ importํ•ด ์ค€๋‹ค.

+ useState์™€ ๋‹ค๋ฅธ์ ์„ ๋ณด์ž

[state, setState] = useState(); ๋ผ๊ณ  ์„ ์–ธํ–ˆ์ง€๋งŒ

์ „์—ญ์— ์žˆ๋Š” recoil์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค

ํŒ
  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์œ„์— ์„ค๋ช…ํ•œ useState ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด useRecoilState ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ,
  • state (value) ์—๋งŒ ์ ‘๊ทผ(๋ถˆ๋Ÿฌ์˜ค๊ธฐ) ํ•˜๊ณ ์‹ถ์„ ๋•Œ๋Š” useRecoilValue ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค,
  • SetState (setter) ํ•จ์ˆ˜๋กœ state๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” useSetRecoilState ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๊ทธ๋ž˜์„œ ๋‚˜๋Š” ๋กœ๊ทธ์•„์›ƒ ํ›„ ๋กœ๊ทธ์•„์›ƒ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด useSetRecoilState๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. ์ดํ›„ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์— ์‚ฌ์šฉํ•ด ๋ณด์ž

import { userLoginCheck as recoilUserLoginCheck } from "@/lib/recoil";
import { useRecoilState } from "recoil";

const [userCheck, setUserCheck] = useRecoilState(recoilUserLoginCheck);

const getSessionUser = async () => {
const { data, error } = await supabase.auth.getSession();
if (error) {
throw new Error(error.message);
}
if (data.session) {
setUserCheck(true);
} else {
setUserCheck(false);
}
};

<ButtonWrapper
onClick={() =>
router.push(userCheck ? "/create-post" : "/auth/login")
}
>

์ „๊ณผ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•  recoil์ธ userLoginCheck ํ•จ์ˆ˜๋ฅผ import ํ•ด ์˜ค๊ณ  useRecoilState๋กœ useState์ฒ˜๋Ÿผ ๊ฐ€์ ธ์™”๋‹ค.

getSessionUser๋ผ๋Š” ํ•จ์ˆ˜์—์„œ๋Š” ๋น„๋™๊ธฐ๋กœ supabase์— auth(์ธ์ฆ) ์„ ์ ‘๊ทผํ•˜์—ฌ ์„ธ์…˜์„ ๊ฐ€์ ธ์˜ค๊ณ  ์žˆ๋‹ค.

๋งŒ์•ฝ ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค๋ฉด ๋จผ์ € Error๋ฅผ throw ํ•ด ์ฃผ๊ณ , data.session์ด ์žˆ๋‹ค๋ฉด, recoil๋กœ ๊ฐ€์ ธ์˜จ setUserCheck๋ฅผ true๋กœ ๋ณ€ํ™˜, ์•„๋‹ˆ๋ผ๋ฉด ๋ฐ˜๋Œ€. ์ฆ‰ ์œ ์ €๊ฐ€ ์žˆ๋Š”์ง€ ์—†๋Š”์ง€ true / false ๋กœ ๋ถ„๋ฅ˜ ํ–ˆ๋‹ค.

๊ธ€์“ฐ๊ธฐ ์•„์ด์ฝ˜ ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์œ„ ์ƒํƒœ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ , userCheck ๊ฐ€ ์žˆ์œผ๋ฉด ๋กœ๊ทธ์ธ์ƒํƒœ์ด๋ฏ€๋กœ ๊ธ€์“ฐ๊ธฐ ํŽ˜์ด์ง€๋กœ, ์•„๋‹ˆ๋ผ๋ฉด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ ์‹œ์ผฐ๋‹ค.


์ตœ์ข… ์ •๋ฆฌ
  1. ๊ธฐ๋ณธ์ ์œผ๋กœ ์œ„์— ์„ค๋ช…ํ•œ useState ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด useRecoilState๋ฅผ ์‚ฌ์šฉ.
  2. state (value) ์—๋งŒ ์ ‘๊ทผ(๋ถˆ๋Ÿฌ์˜ค๊ธฐ) ํ•˜๊ณ ์‹ถ์„ ๋•Œ๋Š” useRecoilValue๋ฅผ ์‚ฌ์šฉ.
  3. SetState (setter) ํ•จ์ˆ˜๋กœ state๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” useSetRecoilState๋ฅผ ์‚ฌ์šฉ.
  4. const { data, error } = await supabase.auth.getSession(); ์œผ๋กœ ์œ ์ € ์„ธ์…˜์— ์ ‘๊ทผ ๊ฐ€๋Šฅ.