Carryduo - 설정 페이지

Charley1013·2022년 10월 14일

Carryduo

목록 보기
7/7

🐭 설정 페이지 설명해줘

설정 페이지

카카오 로그인을 통해 평판 등록이 가능한 유저의 상세 정보를 변경하는 페이지입니다. 추가로 카카오 로그인 유저는 국적 선택, 테두리 색상 커스텀이 가능한 옵션을 추가했습니다.

국적 설정

next-i18n을 사용해 다국어 지원을 할 예정이었지만 그만큼 큰 규모는 아니었고 api route로 직접 api를 만들어서 사용해 보고 싶어 해당 방식을 이용해 국적 선택에 따라 챔피언 언어가 다르게 설정했다

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    const { data } = await instance.get("/champ");
    if (req.query.locale == "en") {
      const Data = data.map((val: Champions) => {
        return val.champNameEn;
      });
      res.status(200).json(Data);
    } else {
      const Data = data.map((val: Champions) => {
        return val.champNameKo;
      });
      res.status(200).json(Data);
    }
  } catch (error) {
    res.status(500).json({ error: "failed" });
  }
}

함수 인자에 들어가는 string 값에 따라 출력하는 api가 다르게 설정했습니다

export const useGetChampionName = (locale?: string) => {
  return useQuery<IChampionName, ErrorHandle, string[]>(
    ["ChampName"],
    () => {
      return axios.get(`/api/locale?locale=${locale}`);
    },
    {
      select: (data) => data.data,
    }
  );
};

테투리 색상 커스텀

페이지 컨테이너 테두리 색상을 커스텀 가능하게 했습니다. 해당 색상을 설정하면 테두리 색상과 함께 라인 애니메이션, border 색상 역시 커스텀 색상과 동일하게 설정했습니다. 색상 값은 recoil을 사용해 로컬 스토리지를 통해 전역으로 사용했습니다.

<div
  className={`z-50 h-[85%] w-[80%] overflow-hidden rounded-xl bg-black bg-opacity-30 px-10 shadow-[0_0_40px_1px]  ${
    color === 1
      ? "shadow-blue-100"
      : color === 2
      ? "shadow-[#5F99FF]"
      : color === 3
      ? "shadow-[#00D39E]"
      : color === 4
      ? "shadow-[#FF7637]"
      : "shadow-gray-700"
  }`}
></div>;
export function useShadow(atom: RecoilState<any>) {
  const [isInitial, setIsInitial] = useState<boolean>(true);
  const [atomName, SetAtomName] = useRecoilState(atom);

  useEffect(() => {
    setIsInitial(false);
  }, []);

  return [isInitial === true ? false : atomName, SetAtomName];
}

프로필 설정

react-hook-form 라이브러리를 사용해 유호성 검사와 별도의 useState, onChange 함수 없이 라이브러리 옵션으로 간편하게 프로필 수정 폼을 만들었습니다. 추가로 티어, 포지션의 이미지 라디오를 구현하기 위해 css module을 수정했습니다

// react-hook-form setting
interface FormProps {
  nickName: string;
  position: string;
  tier: string;
  bio: string;
  preferPosition: string;
}

const defaultValues = {
    nickName: profile?.nickname,
    bio: profile?.bio,
    tier: String(profile?.tier),
    preferPosition: profile?.preferPosition,
    enableChat: profile?.enableChat,
  };

const { register, handleSubmit, watch, reset } = useForm<FormProps>({
  defaultValues,
});
/* 기존 radio 스타일 제거 */
input[type=radio] {
  width: 0;
  height: 0;
  position: absolute;
  left: -9999px;
 }

이슈

- react hook form defaultvalue값 watch로 바로 안 보이는 문제

설정 페이지로 들어왔을 때 프로필 데이터가 바로 보이지 않았던 현상이 있었습니다. 해당 이슈는 useForm에 defaultValues 옵션을 사용해 기존 데이터를 미리 가져왔고 api 값 업데이트 될 때마다 reset를 사용해 기존 데이터를 refresh 시켰습니다.

const { register, handleSubmit, watch, reset } = useForm<FormProps>({
    defaultValues,
  });
  useEffect(() => {
    if (profile) reset({ ...defaultValues });
  }, [profile]);

- 로그인 유저가 없어도 계속해서 api가 호출되는 이슈

설정 페이지에 입장하는 순간 토큰을 가지고 있는 유저의 정보를 호출하는 페이지인데 로그인하지 않은 상태에서도 api를 호출하는 건 비용적 측면에서 좋지 않다 생각해 방법을 찾던 중 현재 사용하는 react-query 라이브러리에 enable 옵션을 사용해 토큰이 없을시 api 호출 자체를 하지 않도록 설정했습니다.

const Token = getCookie("myToken") === undefined ? false : true;

export const useGetUserId = () => {
  return useQuery<userOptions, ErrorHandle, userId>(
    ["getUserId"],
    () => {
      return instance.get("/user");
    },
    {
      select: (data) => data.data,
      enabled: Token,
    }
  );
};
profile
프론트엔드 개발자 김찰리

0개의 댓글