동네 고양이 돌봄 플랫폼!😻 디스캐치 리팩토링

정진우·2022년 3월 4일
0
post-thumbnail

2021년 9월부터 약 3개월동안 만들었던 프로젝트의 코드를 오랜만에 리뷰해 보았다.
리팩토링해야 할 부분들이 정말 많았고, 그 중에 한 부분인 토스트 팝업을
적용한 부분에 대해 리팩토링한 과정을 공유해보고자 한다.


🐱 어떤 기능?

  • 토스트 팝업

유저의 사용감을 향상시키기 위해 기본 alert 대신에 토스트 팝업을 적용했다.
컴포넌트에서 보여줘야 하는 내용이 사용자 인터랙션에 따라 바뀌어야 했기 때문에
useState 훅을 사용해 상태를 관리해줬다.

const [toastState, setToastState] = useState(false);
if (nickName === "" || nickName === null || nickName === undefined) {
    setToastState(true);
} else if {
...생략
    
{toastState && <Toast message="닉네임을 입력해주세요!" />}

만약, 닉네임 입력란이 비어있다면 toastState값이 true로 변경되고
토스트 팝업이 나타나게 된다.

그리고 toastState를 false로 초기화시켜 주어야 하기 때문에 useEffect 훅을 사용했다.

useEffect(() => {
    if (toastState) {
      setTimeout(() => {
        setToastState(false);
      }, 1500);
    }
  }, [toastState]);

toastState값이 변경되면 useEffect 훅이 실행되고 toastState의 값이 true라면
1500 밀리초 후에 초기값인 false로 다시 변경하는 방식이다.

😱 어떤 문제?

useEffect(() => {
    if (toastState) {
      setTimeout(() => {
        setToastState(false);
      }, 1500);
    }
  }, [toastState]);
  
 useEffect(() => {
    if (secondToastState) {
      setTimeout(() => {
        setSecondToastState(false);
      }, 1500);
    }
  }, [secondToastState]);
 
 useEffect(() => {
    if (editToastState) {
      setTimeout(() => {
        setEditToastState(false);
      }, 1500);
    }
  }, [editToastState]);
  
 useEffect(() => {
    if (userToastState) {
      setTimeout(() => {
        setUserToastState(false);
      }, 1500);
    }
  }, [userToastState]);
 
 useEffect(() => {
    if (maxTextState) {
      setTimeout(() => {
        setMaxTextState(false);
      }, 1500);
    }
  }, [maxTextState]);

위와 같이 동일한 구조의 useEffect 훅이 점점 많아졌고, 전체 프로젝트에서
36번이나 반복된다는 사실을 알게 되었다. 기능은 문제없이 잘 실행되고 있었지만,
코드가 너무 길어져 가독성이 떨어지고 나중에 setTimeout의 시간 값을 바꾸는 경우,
수정이 굉장히 힘들 것이라는 생각이 들었다.

🤔 어떻게 해결?

src --> hooks --> useToast.js

import { useEffect } from "react";

function useToast(state, setState) {
  useEffect(() => {
    if (state) {
      setTimeout(() => {
        setState(false);
      }, 1500);
    }
  }, [state, setState]);
}

export default useToast;

상태값(state)과 상태값을 변경시키는 함수(setState)를
인자로 받는 useToast라는 커스텀 훅을 만들었으며,
아래와 같이 조금 더 깔끔하게 코드를 작성할 수 있었다.

import useToast from "../../hooks/useToast";

useToast(toastState, setToastState);
useToast(secondToastState, setSecondToastState);
useToast(editToastState, setEditToastState);
useToast(userToastState, setUserToastState);
useToast(maxTextState, setMaxTextState);



import { _deleteToast } from "../../redux/modules/cat";

const deleteToast = useSelector((state) => state.cat.deleteToast);

useEffect(() => {
    if (deleteToast) {
      setTimeout(() => {
        dispatch(_deleteToast(false));
      }, 1500);
    }
  }, [deleteToast]);

위와 같이 useSelector 훅과 useEffect 훅을 사용해서 코드를 작성한 부분도
5번 반복되고 있었고, useToast를 만들었던 방식과 동일한 방식으로
useDispatchToast라는 커스텀 훅도 만들었다.

src --> hooks --> useDispatchToast.js

import { useEffect } from "react";
import { useDispatch } from "react-redux";

function useDispatchToast(state, toast) {
  const dispatch = useDispatch();
  useEffect(() => {
    if (state) {
      setTimeout(() => {
        dispatch(toast(false));
      }, 1500);
    }
  }, [state, toast, dispatch]);
}

export default useDispatchToast;

✨ 얼마나 깔끔해졌는가?

  • 커스텀 훅을 이용한 결과 159줄의 코드를 줄일 수 있었다.


GitHub

디스캐치 FE 깃허브

profile
프론트엔드 개발자를 꿈꾸는

0개의 댓글