개인 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>
);
}
변경하고 누르면 바로 화면 깜빡이지 않고 반영이 되게 성공!
프로필 업데이트 문제도.. 역시 터질 줄 알았기 때문에 혹시나가 역시나였다.
이게 단계별로 해결해 나가는 맛이 있어서 그런지 시간 가는 줄 모르고 밤새 작업했던 것 같고, 너무 쉽고 당연한 부분들을 모르는게 너무 나 자신에게 실망스럽다. 그리고 맨날 까먹는게 너무 싫다..