[TIL] 개인 : MBTI 테스트 페이지2

최유나·2024년 9월 11일
0

TIL

목록 보기
26/34

MBTI 검사 페이지 만들기

개인 MBTI 검사 페이지 만들기 두번째

회원가입/로그인 기능

프로필 변경

트러블 슈팅

원본 코드

//API 
export const updateProfile = async (token, userData) => {
  const response = await axios.patch(
    `${API_URL}/profile`,
    // 변경할 닉네임을 userData로 받음
    { nickname: userData.nickname },
    {
      headers: {
        Authorization: `Bearer ${token}`
      }
    }
  );
  return response.data;
};
import { useState } from 'react';
import { updateProfile } from '../../api/auth';
import { useMutation } from '@tanstack/react-query';

import useAuthStore from '../../store/AuthStore';

export default function Profile() {
  const [nickname, setNickname] = useState('');
  const token = useAuthStore((state) => state.accessToken);

  const mutation = useMutation({
    mutationFn: (newNickname) => updateProfile(token, { nickname: newNickname }),
    onSuccess: (data) => {
      console.log('프로필 업데이트 성공:', data);
      localStorage.setItem('nickname', nickname);
    },
    onError: (error) => {
      console.error('닉네임 변경 실패:', error);
    }
  });

  const handleNicknameChange = async () => {
    mutation.mutate(nickname);
  };

  return (
    <div>
      <h1>프로필 업데이트</h1>
      <input type="text" value={nickname} onChange={(e) => setNickname(e.target.value)} placeholder="새 닉네임" />
      <button onClick={handleNicknameChange}>닉네임 변경</button>
    </div>
  );
}

처음 닉네임을 가입 데이터에서 받아 로컬스토리지에 저장하고 닉네임을 바꾸는 로직을 완성 한뒤 테스트를 해보니 바로 바뀌어서 들어가지 않는 상황이 발생했다.

게다가 state로 관리하다 보니 전역에서 사용하는데에 문제가 많았다.
그리고 로그인 로그아웃도 그 페이지 내에서 로컬 스토리지에 저장했다가 지우는 형식이었기 때문에 다른곳에서 쓰려면 상태관리가 필요했기에 우선 로그인 로그아웃 데이터 저장 부분부터 차례차례 해 나갔던 것같다.

그러다 로그인을 하고 프로필 네임을 전역상태로 관리해야 하는 상황(네비게이션)에 들어가야 하는 상황이 생겼기에 zustand를 사용해 전역으로 닉네임 업데이트 시 바로 반영되고 즉시 닉네임 변경이 되게 처리 하였다.

import { create } from 'zustand';

const useAuthStore = create((set) => ({
  // 초기값을 localStorage에서 가져옴
  accessToken: localStorage.getItem('accessToken') || null,
  nickname: localStorage.getItem('nickname') || null,
  userId: null,

  // 닉네임 업데이트
  setNickname: (nickname) => {
    set({ nickname });
    localStorage.setItem('nickname', nickname);
  },

}));
export default useAuthStore;

일단 React Query의 useMutation을 활용하여 서버로 닉네임 변경 요청을 보낸 후, 성공하면 Zustand의 setNickname을 호출해 상태를 업데이트하게끔 하여, 새로고침 없이도 화면에서 닉네임이 즉시 반영되게 처리 하였다.
그 다음 프로필 페이지 내에서 onSuccess에서 닉네임을 useAuthStore의 상태에 저장하고, localStorage에도 동기화하도록 변경하였다.

아마 그 후에 query 부분의 훅을 따로 빼서 외부 함수로 만들어서 적용 한 것 같다.
그 부분은 다음편에..

import { useState } from 'react';
import { useProfile } from '../../core/hooks/useAuth';
import Button from '../common/ui/Button';
import Input from '../common/ui/Input';
import Article from '../common/ui/Article';

export default function Profile() {
  const [nickname, setNickname] = useState('');
  const { mutate } = useProfile();

  const handleNicknameChange = () => {
    mutate(nickname);
  };

  return (
    <Article className="Profile">
      <h1 className="mb-6 text-3xl text-black">프로필 업데이트</h1>

      <form onSubmit={(e) => e.preventDefault()} className="w-full space-y-4">
        <Input type="text" value={nickname} onChange={(e) => setNickname(e.target.value)} placeholder="새 닉네임" />
        <Button onClick={handleNicknameChange} className="w-full p-2">
          변경 하기
        </Button>
      </form>
    </Article>
  );
}

현재 프로필 닉네임 부분

변경하고 누르면 바로 화면 깜빡이지 않고 반영이 되게 성공!

회고

프로필 업데이트 문제도.. 역시 터질 줄 알았기 때문에 혹시나가 역시나였다.
이게 단계별로 해결해 나가는 맛이 있어서 그런지 시간 가는 줄 모르고 밤새 작업했던 것 같고, 너무 쉽고 당연한 부분들을 모르는게 너무 나 자신에게 실망스럽다. 그리고 맨날 까먹는게 너무 싫다..

틀린 부분이 있으면 많은 지적 부탁드립니다!

0개의 댓글

관련 채용 정보