ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,47 @@
+import { FollowUserType, followList } from '@/types/types';
+import axios from 'axios';
+import { SetterOrUpdater } from 'recoil';
+
+const PER_PAGE = 100;
+export const getFollowingList = async (setFollowings: SetterOrUpdater<followList[]>, tokenValue: string) => {
+  try {
+    const followingData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/following?per_page=${PER_PAGE}`, {
+      headers: {
+        Accept: 'application/vnd.github+json',
+        Authorization: `Bearer ${tokenValue}`,
+      },
+    });
+
+    const data = followingData.data;
+
+    const followingList = data.map((user: FollowUserType) => {
+      const { id, login, avatar_url } = user;
+      return { id, login, avatar_url };
+    });
+
+    setFollowings(followingList);
+  } catch {
+    console.error('error');
+  }
+};
+
+export const getFollowerList = async (setFollowers: SetterOrUpdater<followList[]>, tokenValue: string) => {
+  try {
+    const followerData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/followers?per_page=${PER_PAGE}`, {
+      headers: {
+        Accept: 'application/vnd.github+json',
+        Authorization: `Bearer ${tokenValue}`,
+      },
+    });
+    const data = followerData.data;
+
+    const followerList = data.map((user: FollowUserType) => {
+      const { id, login, avatar_url } = user;
+      return { id, login, avatar_url };
+    });
+
+    setFollowers(followerList);
+  } catch {
+    console.error('error');
+  }
+};

리뷰: 현재 이렇게 recoil 의 setter 를 받아 사용하도록 되어있는 상황에서는 상위에서 항상 recoil과 함께 사용해야 하는 의존성이 생겨서 함수의 사용 방식이 특정 방법으로 강제돼요. 그런데 그럴 필요가 있을까요? 만약 recoil이 아닌 useState를 사용하도록 변경된다면 어떻게 될까요?

그리고 이 함수는 한번에 두 가지 일을 하고 있어요.
1. 서버에서 팔로워 목록을 불러온다.
2. Follower 상태에 값을 설정한다.

getFollowerList 함수를 서버에서 팔로워 목록을 불러오는 역할만 하게 하고, 값 설정은 이 함수를 사용하는 쪽에서 하면 이 함수를 더 유연하게 사용할 수 있어요.

```suggestion
export const getFollowerList = async (setFollowers: SetterOrUpdater<followList[]>, tokenValue: string) => {
    const followerData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/followers?per_page=${PER_PAGE}`, {
      headers: {
        Accept: 'application/vnd.github+json',
        Authorization: `Bearer ${tokenValue}`,
      },
    });
    const data = followerData.data;

    const followerList = data.map((user: FollowUserType) => {
      const { id, login, avatar_url } = user;
      return { id, login, avatar_url };
    });

    return followerList;

};
```
@@ -0,0 +1,35 @@
+'use client';
+
+import FollowList from '@/components/checkfollow/FollowList';
+import { useRecoilValue, useSetRecoilState } from 'recoil';
+import FollowOrNotBtn from '../../components/checkfollow/FollowOrNotBtn';
+import Profile from '../../components/checkfollow/Profile';
+import { putFollowList } from '@/apis/putFollowList';
+import { followState, inputToken, loginClick } from '@/recoil/atoms';
+
+export default function CheckFollow() {
+  const loginClickState = useRecoilValue(loginClick);
+  const inputTokenValue = useRecoilValue(inputToken);
+  const setFollowState = useSetRecoilState(followState);
+
+  async function handleFllow(username: string) {
+    const success = await putFollowList(username, inputTokenValue);
+    if (success) {
+      setFollowState('follow');
+      window.location.reload();
+    }
+  }
+
+  return (
+    <article className="flex flex-col px-[25px] py-[37px]">
+      <Profile />
+      <FollowOrNotBtn />
+      <FollowList />
+      <button
+        onClick={() => handleFllow(loginClickState)}
+        className="mt-[34px] h-[45px] rounded-[5px] border-2 border-solid border-grey02 bg-sub01 text-title01 text-white hover:bg-grey02">
+        맞팔하기
+      </button>
+    </article>
+  );
+}

리뷰: 페이지를 전체 새로고침하면 큰 성능상의 이슈가 있을 것 같은데, 혹시 이렇게 한 이유가 무엇일까요?
@@ -0,0 +1,27 @@
+'use client';
+
+import { followState } from '@/recoil/atoms';
+import { useSetRecoilState } from 'recoil';
+
+export default function FollowOrNotBtn() {
+  const setBtnState = useSetRecoilState(followState);
+
+  const onClickFollow = () => {
+    setBtnState('follow');
+  };
+
+  const onClickNotFollow = () => {
+    setBtnState('not');
+  };
+
+  return (
+    <section className="flex justify-center gap-[50px] px-[65px] py-[15px]">
+      <button className=" filteringFollowButton" onClick={onClickFollow}>
+        맞팔한 사람
+      </button>
+      <button className=" filteringFollowButton" onClick={onClickNotFollow}>
+        맞팔 아닌 사람
+      </button>
+    </section>
+  );
+}

리뷰: 여기서는 FollowOrNotBtn 컴포넌트가 onChange 등의 프롭으로 상위 컴포넌트에 상태 변경을 알리고, 해당 컴포넌트에서 처리하도록 변경하는게 좋을 것 같아요.

관련된 PR: https://github.com/SimSimS-ToyProject-TEAM3/SimSimS-ToyProject-TEAM3/pull/24#discussion_r1436797019
@@ -0,0 +1,34 @@
+export interface ProfileType {
+  login: string;
+  avatar_url: string;
+  bio: string;
+  followers: number;
+  following: number;
+}
+
+export interface followList {
+  id: number;
+  login: string;
+  avatar_url: string;
+  onClick?: () => void;
+}
+export interface FollowUserType {
+  avatar_url: string;
+  events_url: string;
+  followers_url: string;
+  following_url: string;
+  gists_url: string;
+  gravatar_id: string;
+  html_url: string;
+  id: number;
+  login: string;
+  node_id: string;
+  organizations_url: string;
+  received_events_url: string;
+  repos_url: string;
+  site_admin: boolean;
+  starred_url: string;
+  subscriptions_url: string;
+  type: string;
+  url: string;
+}

리뷰: 일반적으로 사용되는 타입스크립트의 컨벤션처럼, 파스칼 케이스로 작성하면 좋을 것 같아요.

https://basarat.gitbook.io/typescript/styleguide#interface
@@ -0,0 +1,14 @@
+import { useRouter } from 'next/navigation';
+
+export default function ConfirmFollowButton() {
+  const router = useRouter();
+
+  const handleOnclick = () => {
+    router.push('/checkfollow');
+  };
+  return (
+    <div className="commonFlex followBackButton  hover:bg-grey02" onClick={handleOnclick}>
+      나의 맞팔 확인하러 가기
+    </div>
+  );
+}

리뷰: onClick 으로 링크를 처리하면 HTML 태그에서 링크를 볼 수 없고, 컨트롤 + 클릭, 우클릭 등의 동작이 먹히지 않는 접근성 이슈가 있어요. 따라서 사이트 내 페이지 이동 링크는 next/link 를 사용해야 해요.
```tsx
<Link href="/checkfollow" className="commonFlex followBackButton hover:bg-grey02">
  나의 맞팔 확인하러 가기
</Link>
@@ -0,0 +1,46 @@
+import { ProfileType, followList } from '@/types/types';
+import { atom } from 'recoil';
+import { recoilPersist } from 'recoil-persist';
+const { persistAtom } = recoilPersist();
+
+export const profileInfo = atom<ProfileType>({
+  key: 'profileInfo',
+  default: {
+    login: '',
+    avatar_url: '',
+    bio: '',
+    followers: 0,
+    following: 0,
+  },
+});
+
+export const followerList = atom<followList[]>({
+  key: 'followerList',
+  default: [{ id: 0, login: '', avatar_url: '' }],
+});
+
+export const followingList = atom<followList[]>({
+  key: 'followingList',
+  default: [{ id: 0, login: '', avatar_url: '' }],
+});
+
+export const followState = atom<string>({
+  key: 'followState',
+  default: 'follow',
+});
+
+export const checkState = atom<boolean>({
+  key: 'checkState',
+  default: false,
+});
+
+export const inputToken = atom<string>({
+  key: 'inputToken',
+  default: '',
+  effects_UNSTABLE: [persistAtom],
+});
+
+export const loginClick = atom<string>({
+  key: 'loginClick',
+  default: ' ',
+});

리뷰: 미세 팁: 이름의 suffix로 Atom 을 붙이면 컴포넌트에서 이를 활용할 때 이름 충돌 문제에서 자유로워질 수 있어요.

```tsx

// 선언
export const profileInfoAtom = atom<ProfileType>({
  key: 'profileInfo',
  default: {
    login: '',
    avatar_url: '',
    bio: '',
    followers: 0,
    following: 0,
  },
});

// 사용할 때
const profileInfo = useRecoilValue(profileInfoAtom);

```
@@ -0,0 +1,47 @@
+import { FollowUserType, followList } from '@/types/types';
+import axios from 'axios';
+import { SetterOrUpdater } from 'recoil';
+
+const PER_PAGE = 100;
+export const getFollowingList = async (setFollowings: SetterOrUpdater<followList[]>, tokenValue: string) => {
+  try {
+    const followingData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/following?per_page=${PER_PAGE}`, {
+      headers: {
+        Accept: 'application/vnd.github+json',
+        Authorization: `Bearer ${tokenValue}`,
+      },
+    });
+
+    const data = followingData.data;
+
+    const followingList = data.map((user: FollowUserType) => {
+      const { id, login, avatar_url } = user;
+      return { id, login, avatar_url };
+    });
+
+    setFollowings(followingList);
+  } catch {
+    console.error('error');
+  }
+};
+
+export const getFollowerList = async (setFollowers: SetterOrUpdater<followList[]>, tokenValue: string) => {
+  try {
+    const followerData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/followers?per_page=${PER_PAGE}`, {
+      headers: {
+        Accept: 'application/vnd.github+json',
+        Authorization: `Bearer ${tokenValue}`,
+      },
+    });
+    const data = followerData.data;
+
+    const followerList = data.map((user: FollowUserType) => {
+      const { id, login, avatar_url } = user;
+      return { id, login, avatar_url };
+    });
+
+    setFollowers(followerList);
+  } catch {
+    console.error('error');
+  }
+};

리뷰: 건영이가 [여기](https://github.com/sopt-web-advanced-study/TOY-PROJECT/pull/13/files#r1436888989)서 남겨주긴 했는데요! 여기서 타입을 camelCase로 지어주다 보니,

`followList`와 `followingList`는 각각 타입, 변수로 완전 다른 의미로 사용되는데요, 한 눈에 파악하기가 어려웠어요! 각 용도에 따라 컨벤션에 맞게 이름을 지어주면 좋을 것 같아요.
@@ -0,0 +1,47 @@
+import { FollowUserType, followList } from '@/types/types';
+import axios from 'axios';
+import { SetterOrUpdater } from 'recoil';
+
+const PER_PAGE = 100;
+export const getFollowingList = async (setFollowings: SetterOrUpdater<followList[]>, tokenValue: string) => {
+  try {
+    const followingData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/following?per_page=${PER_PAGE}`, {
+      headers: {
+        Accept: 'application/vnd.github+json',
+        Authorization: `Bearer ${tokenValue}`,
+      },
+    });
+
+    const data = followingData.data;
+
+    const followingList = data.map((user: FollowUserType) => {
+      const { id, login, avatar_url } = user;
+      return { id, login, avatar_url };
+    });
+
+    setFollowings(followingList);
+  } catch {
+    console.error('error');
+  }
+};
+
+export const getFollowerList = async (setFollowers: SetterOrUpdater<followList[]>, tokenValue: string) => {
+  try {
+    const followerData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/followers?per_page=${PER_PAGE}`, {
+      headers: {
+        Accept: 'application/vnd.github+json',
+        Authorization: `Bearer ${tokenValue}`,
+      },
+    });
+    const data = followerData.data;
+
+    const followerList = data.map((user: FollowUserType) => {
+      const { id, login, avatar_url } = user;
+      return { id, login, avatar_url };
+    });
+
+    setFollowers(followerList);
+  } catch {
+    console.error('error');
+  }
+};

리뷰: (건영이가 써준 to-be의 인자에 setFollowers는 빠지는걸 의도한걸거에요!)

```tsx
export const getFollowerList = async (tokenValue: string) => { ... }
```
@@ -0,0 +1,47 @@
+import { FollowUserType, followList } from '@/types/types';
+import axios from 'axios';
+import { SetterOrUpdater } from 'recoil';
+
+const PER_PAGE = 100;
+export const getFollowingList = async (setFollowings: SetterOrUpdater<followList[]>, tokenValue: string) => {
+  try {
+    const followingData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/following?per_page=${PER_PAGE}`, {
+      headers: {
+        Accept: 'application/vnd.github+json',
+        Authorization: `Bearer ${tokenValue}`,
+      },
+    });
+
+    const data = followingData.data;
+
+    const followingList = data.map((user: FollowUserType) => {
+      const { id, login, avatar_url } = user;
+      return { id, login, avatar_url };
+    });
+
+    setFollowings(followingList);
+  } catch {
+    console.error('error');
+  }
+};
+
+export const getFollowerList = async (setFollowers: SetterOrUpdater<followList[]>, tokenValue: string) => {
+  try {
+    const followerData = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/user/followers?per_page=${PER_PAGE}`, {
+      headers: {
+        Accept: 'application/vnd.github+json',
+        Authorization: `Bearer ${tokenValue}`,
+      },
+    });
+    const data = followerData.data;
+
+    const followerList = data.map((user: FollowUserType) => {
+      const { id, login, avatar_url } = user;
+      return { id, login, avatar_url };
+    });
+
+    setFollowers(followerList);
+  } catch {
+    console.error('error');
+  }
+};

리뷰: 만약 console.error로 만 남겨두고 싶었더라도 이렇게 하면 하드코딩된 'error'만 남게되어 헷갈릴 것 같아요.

`error.message`를 찍거나([mdn 예시](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Error#%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8_%EC%98%A4%EB%A5%98_%EB%8D%98%EC%A7%80%EA%B8%B0)), 아니면 보통 [Sentry](https://docs.sentry.io/platforms/javascript/guides/react/usage/)를 통해 에러를 수집(로깅)해서 에러를 빠르게 확인하고 이를 처리할 수 있도록 하고 있어요!

에러 객체는 `Error` 라는 [내장 객체 타입](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Error)으로 던져지는데요, 이는 name, message, stack를 기본적으로 가지고 있어서 보통 message를 보여주는 식으로 많이 사용해요. (서버쪽에서 에러 메시지를 설정해서 보내준다면, 해당 필드로 확인이 가능한 경우가 대부분이에요.) 만약 타입 지정이 안되는 경우에는 아래처럼 처리할 수 있어요.

```tsx
// 요렇게 하라는 말씀은 아니고 instatnceof 구문으로 타입추론을 할 수 있다는 예시입니다!
try {
} catch(error){
 console.error(error instanceof Error ? error.message : '~에서 에러가 발생했어요 ');
}

```

참고로 에러는 발생한 곳에서 부터 최상위 컴포넌트까지 전파되고, 가장 가까운 catch문이나 에러바운더리를 설정해둔 곳에서 catch될 수 있는데요, 이 경우에는 'catch' 라고만 console.error 로 찍히게 되어 건영이 말 처럼 오히려 헷갈릴 수 있을 것 같습니닷
@@ -0,0 +1,35 @@
+'use client';
+
+import FollowList from '@/components/checkfollow/FollowList';
+import { useRecoilValue, useSetRecoilState } from 'recoil';
+import FollowOrNotBtn from '../../components/checkfollow/FollowOrNotBtn';
+import Profile from '../../components/checkfollow/Profile';
+import { putFollowList } from '@/apis/putFollowList';
+import { followState, inputToken, loginClick } from '@/recoil/atoms';
+
+export default function CheckFollow() {
+  const loginClickState = useRecoilValue(loginClick);
+  const inputTokenValue = useRecoilValue(inputToken);
+  const setFollowState = useSetRecoilState(followState);
+
+  async function handleFllow(username: string) {
+    const success = await putFollowList(username, inputTokenValue);
+    if (success) {
+      setFollowState('follow');
+      window.location.reload();
+    }
+  }
+
+  return (
+    <article className="flex flex-col px-[25px] py-[37px]">
+      <Profile />
+      <FollowOrNotBtn />
+      <FollowList />
+      <button
+        onClick={() => handleFllow(loginClickState)}
+        className="mt-[34px] h-[45px] rounded-[5px] border-2 border-solid border-grey02 bg-sub01 text-title01 text-white hover:bg-grey02">
+        맞팔하기
+      </button>
+    </article>
+  );
+}

리뷰: 전체 새로고침을 하면 사용자 경험 측면에서도 좋지 않을 것 같아요!
@@ -0,0 +1,89 @@
+'use client';
+
+import { getFollowerList, getFollowingList } from '@/apis/getFollowList';
+import { checkState, followState, followerList, followingList, inputToken, loginClick } from '@/recoil/atoms';
+import { followList } from '@/types/types';
+import { useEffect } from 'react';
+import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
+import ListElement from './ListElement';
+
+export default function FollowList() {
+  const [followers, setFollowers] = useRecoilState(followerList);
+  const [followings, setFollowings] = useRecoilState(followingList);
+  const followBtnState = useRecoilValue(followState);
+  const setCheckState = useSetRecoilState(checkState);
+  const inputTokenValue = useRecoilValue(inputToken);
+  const [loginClickState, setLoginClickState] = useRecoilState(loginClick);
+
+  useEffect(() => {
+    getFollowingList(setFollowings, inputTokenValue);
+    getFollowerList(setFollowers, inputTokenValue);
+  }, []);
+
+  const followerID = followers.map(user => user.id);
+  const followingID = followings.map(user => user.id);
+
+  const followEachOther = followings.filter(user => {
+    return followerID.includes(user.id) && user;
+  });
+
+  const notFollowEachOther = followers.filter(user => {
+    return !followingID.includes(user.id) && user;
+  });
+
+  const onClickCheck = () => {
+    setCheckState(true);
+  };
+
+  const onClickRemove = () => {
+    setCheckState(false);
+  };
+
+  useEffect(() => {
+    onClickRemove();
+  }, [followBtnState]);
+
+  function handleClickLogin(login: string) {
+    setLoginClickState(prevlogin => (prevlogin === login ? ' ' : login));
+  }
+
+  useEffect(() => {
+    console.log(loginClickState);
+  }, [loginClickState, setLoginClickState]);
+
+  return (
+    <section className="commonBackground flex h-[480px] w-full flex-col">
+      <div className="flex justify-end gap-[14px] px-[25px] py-[20px]">
+        <button
+          className="commonButton h-[25px] w-[65px] bg-white text-black hover:bg-red hover:text-white"
+          onClick={onClickCheck}>
+          ✔️ 모두 선택
+        </button>
+        <button
+          className="commonButton h-[25px] w-[65px] bg-white text-black hover:bg-red hover:text-white"
+          onClick={onClickRemove}>
+          모두 해지
+        </button>
+      </div>
+      <div className="flex h-[350px] w-[340px] flex-col gap-[20px] overflow-scroll py-[5px]">
+        {followBtnState === 'follow'
+          ? followEachOther.map((user: followList) => {
+              const { id, login, avatar_url } = user;
+              return <ListElement key={id} id={id} login={login} avatar_url={avatar_url} />;
+            })
+          : notFollowEachOther.map((user: followList) => {
+              const { id, login, avatar_url } = user;
+              return (
+                <ListElement
+                  onClick={() => handleClickLogin(login)}
+                  key={id}
+                  id={id}
+                  login={login}
+                  avatar_url={avatar_url}
+                />
+              );
+            })}
+      </div>
+    </section>
+  );
+}

리뷰: 디버깅용으로 사용한 다음엔 지우면 좋을 것 같습니닷 ㅎㅎ
@@ -0,0 +1,14 @@
+import { useRouter } from 'next/navigation';
+
+export default function ConfirmFollowButton() {
+  const router = useRouter();
+
+  const handleOnclick = () => {
+    router.push('/checkfollow');
+  };
+  return (
+    <div className="commonFlex followBackButton  hover:bg-grey02" onClick={handleOnclick}>
+      나의 맞팔 확인하러 가기
+    </div>
+  );
+}

리뷰: 요렇게 아래에 어디로 이동할건지 프리뷰로도 알려준답니당! Link는 next.js에서 `<a>` 태그를 래핑해준 컴포넌트에요. (실제로 말한 접근성은 a태그가 챙겨주는 것 입니당)

<img width="1624" alt="image" src="https://github.com/sopt-web-advanced-study/TOY-PROJECT/assets/26808056/af8d6f55-393a-49ba-be04-f00972a2a478">
@@ -0,0 +1,14 @@
+import { useRouter } from 'next/navigation';
+
+export default function ConfirmFollowButton() {
+  const router = useRouter();
+
+  const handleOnclick = () => {
+    router.push('/checkfollow');
+  };
+  return (
+    <div className="commonFlex followBackButton  hover:bg-grey02" onClick={handleOnclick}>
+      나의 맞팔 확인하러 가기
+    </div>
+  );
+}

리뷰: 소소한 내용인데, 이벤트 핸들러 함수 이름을 지을땐 보통

`onClick~`
`handleClick~`

둘 중 하나로 짓는 것 같아요. 접두사가 둘 다 붙어있어서 남겨봤습니다!
@@ -0,0 +1,34 @@
+export interface ProfileType {
+  login: string;
+  avatar_url: string;
+  bio: string;
+  followers: number;
+  following: number;
+}
+
+export interface followList {
+  id: number;
+  login: string;
+  avatar_url: string;
+  onClick?: () => void;
+}
+export interface FollowUserType {
+  avatar_url: string;
+  events_url: string;
+  followers_url: string;
+  following_url: string;
+  gists_url: string;
+  gravatar_id: string;
+  html_url: string;
+  id: number;
+  login: string;
+  node_id: string;
+  organizations_url: string;
+  received_events_url: string;
+  repos_url: string;
+  site_admin: boolean;
+  starred_url: string;
+  subscriptions_url: string;
+  type: string;
+  url: string;
+}

리뷰: 그리고 서버에서 사용되는 타입과 (api 호출 결과 알려주는 타입) 실제 컴포넌트에서 사용하는 타입은 구분되었으면 좋겠어요! (model.ts 라는 형식으로 짓기도 하는데, api 호출 결과 응답으로 받는 타입을 적는 파일이에요.)

이렇게 onClick 이라는 컴포넌트에서 적용되는 논리의 타입을 가지고 있을 경우 api의 타입이 변경되어 해당 타입을 바꿔주었는데, 컴포넌트에서까지 영향을 받을 수 있어요! 

만약 서버 타입을 확장해서 사용하고 싶다면, 사용처(컴포넌트쪽)에서 import 한 뒤 확장해서 사용하는게 더 좋을 것 같아요.

```tsx
// 이렇게요!
interface 팔로우어쩌구ComponentProps {
 onClick?: ()=>void;
} extends FollowList

// 그런데 사실 모델만 가져오는게 더 좋을 것 같아요.
interface 팔로우어쩌구ComponentProps {
 followList: FollowList[]; // 서버 타입이 변경되면, followList만 변경이 이뤄지면 돼요. 변경의 영향 범위를 최소한으로 만들어줄 수 있어요.
 onClick?: ()=>void;
};
```
@@ -0,0 +1,46 @@
+import { ProfileType, followList } from '@/types/types';
+import { atom } from 'recoil';
+import { recoilPersist } from 'recoil-persist';
+const { persistAtom } = recoilPersist();
+
+export const profileInfo = atom<ProfileType>({
+  key: 'profileInfo',
+  default: {
+    login: '',
+    avatar_url: '',
+    bio: '',
+    followers: 0,
+    following: 0,
+  },
+});
+
+export const followerList = atom<followList[]>({
+  key: 'followerList',
+  default: [{ id: 0, login: '', avatar_url: '' }],
+});
+
+export const followingList = atom<followList[]>({
+  key: 'followingList',
+  default: [{ id: 0, login: '', avatar_url: '' }],
+});
+
+export const followState = atom<string>({
+  key: 'followState',
+  default: 'follow',
+});
+
+export const checkState = atom<boolean>({
+  key: 'checkState',
+  default: false,
+});
+
+export const inputToken = atom<string>({
+  key: 'inputToken',
+  default: '',
+  effects_UNSTABLE: [persistAtom],
+});
+
+export const loginClick = atom<string>({
+  key: 'loginClick',
+  default: ' ',
+});

리뷰: 컴포넌트의 사용처에서 확인해보니 `'follow' | 'not'` 두 가지 경우로 사용되는 것 같은데요, 그렇다면 atom의 타입을 string으로 적어주기 보다는 아래처럼 나타내는게 더 좋을 것 같아요.(string literal type, enum 타입 이라고도 불러요) 실제 IDE에서 타입 추론을 해주어 휴먼에러를 방지해주기 위함이에요.

그리고 follow, not 의 두 가지 논리만 존재한다면 `boolean` 타입으로 두어도 괜찮을 것 같습니다! 

```suggestion
export const followState = atom<'follow' | 'not'>({
  key: 'followState',
  default: 'follow',
});
```
@@ -0,0 +1,46 @@
+import { ProfileType, followList } from '@/types/types';
+import { atom } from 'recoil';
+import { recoilPersist } from 'recoil-persist';
+const { persistAtom } = recoilPersist();
+
+export const profileInfo = atom<ProfileType>({
+  key: 'profileInfo',
+  default: {
+    login: '',
+    avatar_url: '',
+    bio: '',
+    followers: 0,
+    following: 0,
+  },
+});
+
+export const followerList = atom<followList[]>({
+  key: 'followerList',
+  default: [{ id: 0, login: '', avatar_url: '' }],
+});
+
+export const followingList = atom<followList[]>({
+  key: 'followingList',
+  default: [{ id: 0, login: '', avatar_url: '' }],
+});
+
+export const followState = atom<string>({
+  key: 'followState',
+  default: 'follow',
+});
+
+export const checkState = atom<boolean>({
+  key: 'checkState',
+  default: false,
+});
+
+export const inputToken = atom<string>({
+  key: 'inputToken',
+  default: '',
+  effects_UNSTABLE: [persistAtom],
+});
+
+export const loginClick = atom<string>({
+  key: 'loginClick',
+  default: ' ',
+});

리뷰: 해당 변수들이 각 컴포넌트에 import 되어 재사용되다 보니 아톰을 나타내는건지 한눈에 이름으로도 알 수 있게 `~State`나 `~Atom`등의 접미사를 붙여서 이름이 구분되어도 좋을 것 같습니닷

(아래의 followState와 같이요!)
@@ -0,0 +1,46 @@
+import { ProfileType, followList } from '@/types/types';
+import { atom } from 'recoil';
+import { recoilPersist } from 'recoil-persist';
+const { persistAtom } = recoilPersist();
+
+export const profileInfo = atom<ProfileType>({
+  key: 'profileInfo',
+  default: {
+    login: '',
+    avatar_url: '',
+    bio: '',
+    followers: 0,
+    following: 0,
+  },
+});
+
+export const followerList = atom<followList[]>({
+  key: 'followerList',
+  default: [{ id: 0, login: '', avatar_url: '' }],
+});
+
+export const followingList = atom<followList[]>({
+  key: 'followingList',
+  default: [{ id: 0, login: '', avatar_url: '' }],
+});
+
+export const followState = atom<string>({
+  key: 'followState',
+  default: 'follow',
+});
+
+export const checkState = atom<boolean>({
+  key: 'checkState',
+  default: false,
+});
+
+export const inputToken = atom<string>({
+  key: 'inputToken',
+  default: '',
+  effects_UNSTABLE: [persistAtom],
+});
+
+export const loginClick = atom<string>({
+  key: 'loginClick',
+  default: ' ',
+});

리뷰: 요게 정확히 어떤걸 위해 사용되는 atom인지가 이름이나 default 값만 보고는 조금 파악하기가 어려운 것 같아요 ㅠㅠ 그리고 기본값이 그냥 다른 값처럼 빈 스트링이 아니라 `' '` 인 이유도 혹시 있을까요?!

아톰을 사용할 때, 어디에 어떤 목적으로 사용되는지를 이름에 더 나타내고, 기본값을 잘 설정해서 어떤 용도로 어떻게 사용하는지 좀 더 잘 드러내고, 궁극적으로는 아톰을 꼭 사용해야 하는지 한번 더 고민을 해보는 것도 좋은 고민이 될 것 같아요!