hook을 통한 관심사 분리

김윤진·2022년 9월 15일
3

React

목록 보기
9/13

레벨로그 프로젝트

1. Team을 보여주는 컴포넌트를 작성

// Team.jsx
const Team = () => {
  const [team, setTeam] = useState([])
  
  const requestGetTeam = ({}) => {
  	return axios(
      method: 'get',
      url: `${process.env.API_URI}/team`,
  	);
  };

  const getTeam = async () => {
    const response = await requestGetTeam();
    setTeam(response.data);
  }
  
  useEffect(() => {
    getTeam();
  }, []);
  
  return (
    <>
       {teams.map((team: InterviewTeamType) => (
         <InterviewTeam key={team.id} team={team} />
       ))}
    </>
  )
}

여기서 불편함을 느낄 수 있다.
비즈니스 로직에 대한 수정이 필요한 경우 해당하는 컴포넌트 파일에 가서 수정을 해야하는 번거로움이 있다. 이는 프로젝트의 크기가 커지면 커질 수록 비용은 그에 비례해서 커진다.

그렇다면 UI 로직과 비즈니스 로직을 분리해보자.
UI 로직과 비즈니스 로직을 분리하는 것은 상당히 강조되어왔던 사항이다.
React에서는 hook을 통해 관심사를 분리할 수 있다.
상당히 간단하다.


2. UI 로직과 비즈니스 로직 분리

// team.js
const useTeam = () => {
  const [team, setTeam] = useState([])
  
  const requestGetTeam = ({}) => {
  	return axios(
      method: 'get',
      url: `${process.env.API_URI}/team`,
  	);
  };

  const getTeam = async () => {
    const response = await requestGetTeam();
    setTeam(response.data);
  }
  
  useEffect(() => {
    getTeam();
  }, [])
 
  return {
    team,
  }
}


// Team.jsx
const Team = () => {
  const { team } = useTeam(); 
  
   return (
    <>
       {teams.map((team: InterviewTeamType) => (
         <InterviewTeam key={team.id} team={team} />
       ))}
    </>
  )
}

이렇게 관심사를 분리하면 비즈니스 로직의 수정이 필요한 경우 hook을 찾아보면 되고 UI 변경이 생긴다면 컴포넌트를 보면 된다.


3. hook의 계층 분리

비즈니스 코드를 훅에 작성하다보면 훅의 크기가 점점 커지는 경우가 생긴다. 이럴 때는 계층을 분리해, 훅을 가볍게 해서 훅의 가독성을 높이는 것 방법이 있다.
일단 axios를 분리하고 CRUD 로직을 hook의 첫번째 계층을 분리한다. 그리고 UI 로직에 필요한 로직들을 두번째 계층으로 분리한다.

// api/team.js
export const requestGetTeam = ({}) => {
  	return axios(
      method: 'get',
      url: `${process.env.API_URI}/team`,
  	);
  };

// axios crud코드...

첫번째 계층에서는 axios를 통해 api 통신하는 결과를 받아온다. 그리고 통신한 결과에 대한 성공 처리나 에러 처리를 해준다. axios 코드에서 함수로 한번 감싸주는 형식이라고 생각하면 쉽다.

// useTeam.js
import { requestGetTeam } from 'api/team';

const useTeam = () => {
  const [team, setTeam] = useState([]);
  
  const getTeam = async () => {
    try {
    const response = await requestGetTeam();
      setTeam(response.data);
      snackbar('요청 성공 스낵바');
      // 요청 성공 처리....
    } catch (e) {
      snackbar('요청 실패 스낵바');
      // 요청 에러 처리....
    }
    // 
  }
}

export {
  team,
  getTeam,
}

두번째 계층에서는 UI 로직에서 필요한 handle... 함수를 선언하고 UI 로직의 이벤트 핸들러에 부착하기 위해 반환한다. 그리고 페이지에 종속적으로 훅을 만들어서 한 페이지의 비즈니스 코드를 작성하는 방법도 있다.

// useTeamPage.js
cosnt useTeamPage = () => {
  cosnt { team, getTeam } = useTeam();
  
  const handleTeamButtonClick = () => {
    // 클릭이벤트에 필요한 로직
  }
  
  return {
    team,
    handleTeamButtonClick,
  }
}

이렇게 계층을 나누는 기준은 작성하는 때(서비스, 상황)에 맞는 기준을 세워서 작성하는 것이 좋다. 언제나 절대적인 것이 존재할 가능성은 적기 때문이다.
어쨋든 계층을 나누는 것부터가 코드의 가독성이나 디버깅을 쉽게 하는 것은 맞다. 에러 코드를 보고 어떠한 계층에서 에러가 발생했는지 비교적 쉽게 찾고 찾아가기도 수월하기 때문이다.

0개의 댓글