s e o p p o r t . l o g

Today I Learned

2024.02.21 TIL - PATCH, 로컬스토리지

Seo Ji Won 2024. 2. 21. 20:23

마이페이지에서 프로필 수정 구현하기

마이페이지 컴포넌트

1. 수정사항 확인하기

const handleModifyCompleteButtonClick = async () => {
    // 닉네임과 프로필 이미지 모두 원본데이터와 같으면 수정X
    if (userInfo.nickname === modifiedNickname && userInfo.avatar === imageSrc) {
      alert('수정사항이 없습니다.');
      return;
    }

우선 수정 사항이 없으면 수정이 완료되지 않게 return으로 실행을 끝내준다. 닉네임과 프로필사진 하나라도 변경값이 있으면 수정이 진행된다.

 

2. 수정 할 사용자 정보 작성하기

const updateUserInfo = {avatar: imageSrc, nickname: modifiedNickname};

수정할 사용자의 정보를 객체 형태로 담는다. patch를 사용할 것이기 때문에 수정이 필요한 부분만 작성하면 된다.

 

3.1 편지 DB 서버의 해당 유저가 작성한 편지의 유저 정보 업데이트 

// json server 편지에 프로필 수정
// 편지들 중에 userId가 같은 것만 받아오기

  const {data: targetLetters} = await letterApi.get(`/letters?userId=${userInfo.id}`);
  // targetLetters 배열의 아이디들 배열돌면서 patch
  for (const letters of targetLetters) {
    letterApi.patch(`/letters/${letters.id}`, updateUserInfo);
  }

이 부분이 제일 어려웠는데, 마이페이지에서 유저 정보를 수정하면 유저 정보 뿐만 아니라 db에 있는 사용자가 작성했던 편지의 유저 정보도 수정해야 한다.

일단 GET으로 쿼리스트링을 이용해 해당 사용자가 남긴 편지들(targetLetters)만 받아온다,

그 후 for of로 targetLetters 배열을 돌면서 각각의 편지 id를 PATCH 주소로 설정하고 편지의 유저 정보를 수정한 유저 정보(updateUserInfo)로 업데이트한다.

 

3-2. 로그인 서버의 프로필, 로컬스토리지 업데이트 (필요한 부분 업데이트)

// 서버 프로필 수정
      const res = await loginApi.patch('/profile', updateUserInfo, {
        headers: {Authorization: `Bearer ${userInfo.accessToken}`},
      });

      console.log(res);
      alert(res.data.message);

      //로컬스토리지 수정
      const storageUserInfo = JSON.parse(localStorage.getItem('storageUserInfo'));
      const newUserInfo = {...storageUserInfo, nickname: modifiedNickname, avatar: imageSrc};
      localStorage.setItem('storageUserInfo', JSON.stringify(newUserInfo));
    } catch (error) {
      console.log('error', error);
      alert('알 수 없는 오류가 발생했습니다. 잠시 후 시도해주세요.');
    }

    setIsModifying(false);
  };

마찬가지로 로그인 서버의 프로필과 로컬스토리지에 저장해두었던 유저정보도 업데이트해준다.

로컬스토리지도 업데이트하는 이유는 새로고침에 대응하기 위해 렌더링 될 때마다 로컬스토리지의 값을 dispatch로 유저 정보 리듀서에 넣어주고 있기 때문이다.

3-1과 3-2는 설명을 위해 순번을 붙였을 뿐, 순서가 중요하진 않을 것 같다.

 

다음은 수정 로직 전체 코드이다.

const handleModifyCompleteButtonClick = async () => {
    //닉네임이 바뀌거나, 프로필 이미지가 바뀌면 수정완료
    // 닉네임과 프로필 이미지 모두 같으면 수정 안됨
    if (userInfo.nickname === modifiedNickname && userInfo.avatar === imageSrc) {
      alert('수정사항이 없습니다.');
      return;
    }

    const updateUserInfo = {avatar: imageSrc, nickname: modifiedNickname};

    try {
      // 리덕스 수정
      dispatch(modifyUserInfo({userId: userInfo.id, modifiedNickname, modifiedAvatar: imageSrc}));

      // json server 편지에 프로필 수정
      // 편지들 중에 userId가 같은 것만 받아오기
      const {data: targetLetters} = await letterApi.get(`/letters?userId=${userInfo.id}`);

      // targetLetters 배열의 아이디들 배열돌면서 patch
      for (const letters of targetLetters) {
        letterApi.patch(`/letters/${letters.id}`, updateUserInfo);
      }

      // 서버 프로필 수정
      const res = await loginApi.patch('/profile', updateUserInfo, {
        headers: {Authorization: `Bearer ${userInfo.accessToken}`},
      });

      console.log(res);
      alert(res.data.message);

      //로컬스토리지 수정
      const storageUserInfo = JSON.parse(localStorage.getItem('storageUserInfo'));
      const newUserInfo = {...storageUserInfo, nickname: modifiedNickname, avatar: imageSrc};
      localStorage.setItem('storageUserInfo', JSON.stringify(newUserInfo));
    } catch (error) {
      console.log('error', error);
      alert('알 수 없는 오류가 발생했습니다. 잠시 후 시도해주세요.');
    }

    setIsModifying(false);
  };

 

늘 느끼지만 수정이 제일 어려운 것 같다.

PATCH 요청이 자꾸 404가 떠서 한참 헤맸는데 patch를 쿼리스트링이 아니라 슬래시로 넣어주어야 한다는 것을 몰라서 고생했다. 슬래시로 서버 주소의 값을 특정해서 가져오는 것은 id에 한해서만 가능한듯 하다. 공식문서의 중요함을 깨달은 문제 해결 경험이었다.