TMI - 트러블슈팅 유저 정보 수정 기능

김진주·2024년 2월 24일
0

유저 정보 수정 기능에서 리렌더링이 발생하지 않아 저장하기가 활성화가 되지 않고 선택된 정보가 완전히 적용되지 않는 버그가 있었다.

상위 컴포넌트인 마이페이지에서 변화된 상태를 읽지 못하고 렌더링이 발생시키지 못해 일어나는 일이었다.
그래서 zustand를 사용하여 하위 컴포넌트인 MypageBodyTypeSlide MypageSievingSlide MypageStyleSlide 에서 유저의 정보가 변화되면 마이페이지에서 변화를 감지하여 리렌더링이 발생하도록 하였다.

문제 해결 전

// 수정 전 마이페이지
function Mypage() {
  const { userId } = useParams();

  const { storageData } = useStorage('pocketbase_auth');
  const [authUserData, setAuthUserData] = useState(storageData?.model);
  const [isDisabled, setIsDisabled] = useState(true);

  useEffect(() => {
    setAuthUserData(storageData?.model);
  }, [storageData]);

  let dataItems = postData?.items;

  const storedUserSievingValue = getData('userSievingValue')?.replace(
    /\s/g,
    ''
  );
  const storedUserStyleValue = getData('userStyleValue');
  const storedBodyTypeValue = getData('userBodyTypeValue');

  const handleSaveClick = async () => {
    await pb.collection('users').update(userId, {
      sieving:
        storedUserSievingValue !== null
          ? storedUserSievingValue
          : authUserData?.sieving,
      style:
        storedUserStyleValue !== null
          ? storedUserStyleValue
          : authUserData?.style,
      bodyType:
        storedBodyTypeValue !== null
          ? storedBodyTypeValue
          : authUserData?.bodyType,
    });
  };

  useEffect(() => {
    if (storedUserSievingValue || storedUserStyleValue || storedBodyTypeValue) {
      setIsDisabled(false);
    } else {
      setIsDisabled(true);
    }
  }, [storedUserSievingValue, storedUserStyleValue, storedBodyTypeValue]);

버튼을 클릭할 떄마다 랜더링이 발생하지 않아 저장하기 버튼이 활성화 되지 않고 다른 페이지를 갔다와야 저장된 값을 읽고 disabled가 해제되어 저장하기 버튼을 클릭할 수 있게 된다.

문제 해결 후


버튼을 누를 때마다 리랜더링이 발생하여 저장하기 버튼이 바로 활성화되게 하였고 저장하기 버튼을 누른 후에는 메인페이지로 이동하게 수정하였다.

 try {
      await updateUser(userId, authUserData);

      toast.success('정보가 수정되었습니다.');
      deleteData('userBodyTypeValue');
      deleteData('userSievingValue');
      deleteData('userStyleValue');
      navigate('/');
    } catch (error) {
      toast.error(error);
    }
  };

  const handleLogout = async () => {
    try {
      await signOut();
      localStorage.clear();
      toast.success('로그아웃되었습니다.');
      window.location.reload();
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    checkLogIn();
  }, [checkLogIn]);

  useEffect(() => {
    setAuthUserData(user);
  }, [user]);

  useEffect(() => {
    if (storedUserSievingValue || storedUserStyleValue || storedBodyTypeValue) {
      setIsDisabled(false);
    } else {
      setIsDisabled(true);
    }
  }, [
    storedUserSievingValue,
    storedUserStyleValue,
    storedBodyTypeValue,
    userBodyStyle,
  ]);
// zustand를 사용하여 유저의 바디타입 수정

const initialUserBodyState = {
  userSieving: '',
  userStyle: '',
  userBodyType: '',
};

const useUserStore = create((set) => ({
  ...initialUserBodyState,

  updateUserStyle: async (userId, authUserData) => {
    const storedUserSievingValue = JSON.parse(
      localStorage.getItem('userSievingValue')
    )?.replace(/\s/g, '');
    const storedUserStyleValue = JSON.parse(
      localStorage.getItem('userStyleValue')
    );
    const storedBodyTypeValue = JSON.parse(
      localStorage.getItem('userBodyTypeValue')
    );

    try {
      const updatedUser = pb.collection('users').update(userId, {
        sieving:
          storedUserSievingValue !== null
            ? storedUserSievingValue
            : authUserData?.sieving,
        style:
          storedUserStyleValue !== null
            ? storedUserStyleValue
            : authUserData?.style,
        bodyType:
          storedBodyTypeValue !== null
            ? storedBodyTypeValue
            : authUserData?.bodyType,
      });

      set({
        userSieving: updatedUser.sieving,
        userStyle: updatedUser.style,
        userBodyType: updatedUser.bodyType,
      });
    } catch (error) {
      console.error(error.message, '에러 메시지');
      throw new Error(
        '사용자 정보 업데이트에 실패했습니다. 다시 시도해주세요.'
      );
    }
  },

  setStyle: (userStyle) => set({ userStyle: userStyle }),

  setSieving: (userSieving) => set({ userSieving: userSieving }),

  setBodyType: (userBodyType) => set({ userBodyType: userBodyType }),
}));

export default useUserStore;
<!-- Sieving -->
  const setSieving = useUserStore((store) => store.setSieving);
  const handleSievingClick = async (value) => {
    setData('userSievingValue', value);
    setSieving(value);
  };
<!-- BodyType -->
  const setBodyType = useUserStore((store) => store.setBodyType);

  const handleBodyTypeClick = async (value) => {
    setData('userBodyTypeValue', value);
    setBodyType(value);
  };
<!-- Style -->
 const setStyle = useUserStore((store) => store.setStyle);

  const handleStyleClick = (value) => {
    const storedUserStyleValue = getData('userStyleValue');

    const parsedStoredUserStyleValue = storedUserStyleValue
      ? new Set(storedUserStyleValue)
      : new Set();

    if (!parsedStoredUserStyleValue.has(value)) {
      parsedStoredUserStyleValue.add(value);

      setData('userStyleValue', Array.from(parsedStoredUserStyleValue));
    }
    setStyle(Array.from(parsedStoredUserStyleValue));
  };
profile
진주링딩동🎵

0개의 댓글