본문 바로가기
Developer/Javascript 해부학

클래스 컴포넌트에서 함수 컴포넌트로 전환기

by 해적거북 2024. 3. 17.
728x90

목차

  1. 전환 배경
  2. 상태 변이 콜백 함수
  3. Context Api
  4. 마무리
  5. 참조

배경

Boilerplate_code

사내 코드에 아직 클래스 컴포넌트로 이루어진 프로젝트가 있습니다. 현재 그 프로젝트는 정상적으로 동작하고 간단한 기능 추가 및 유지보수에는 문제 없습니다. 하지만 서비스가 고도화 될수록 복잡한 기능 구현하기 위해 hook으로 지원하는 라이브러리를 자유롭게 사용하지 못했습니다. 고차 컴포넌트(HOC)를 이용하여 사용하는 방법이 있긴 하지만 매 라이브러리마다 고차 컴포넌트를 만드는 것은 유지보수 비용을 더 크게 만드는 것 같다고 판단하여 함수 컴포넌트로 전환하기로 결정했습니다. 이 전환 과정에서 고려해야하는 점들이 있어서 글로 작성하였습니다.


상태 변이 콜백 함수

callback

클래스 컴포넌트의 상태변이는 콜백을 지원합니다. 이 콜백함수는 상태가 변이된 후 동작합니다. 이러한 방식의 실행은 공식문서에서 componentDidUpdate() 메서드를 통해 작성하는 것을 권장합니다.


그런데 함수 컴포넌트에서는 상태변이의 콜백함수를 지원하지 않습니다. 이 부분은 라이브사이클과 관련된 내용이기에 useEffect 훅을 사용하여 처리해야합니다. 자세한 마이그레이션 방법은 공식문서에서 자세히 설명하고 있습니다.


그런데 간혹 기존 클래스 컴포넌트에서 함수 컴포넌트로 전환했는데 상태 변이가 무한 렌더링 되는 경우가 있습니다. 이러한 경우 아예 로직을 새로 작성해야합니다. 한번에 전환하기 곤란한 경우, 먼저 클래스 컴포넌트의 상태변이 콜백함수를 componentDidUpdate() 메서드로 전환하고 나서 함수 컴포넌트로 전환하는 것을 권장합니다.

class ClassComponent extends React.Component {
  getNextPageData() {
    // (api 요청 로직..)

    // 만약 여기서 page상태를 변이하는 동작이 있는 경우
    // 상태 변이의 콜백이 아닌 라이프사이클 메서드로 동작함.
  }

  async handleChangePage(nextPage) {
    this.setState({ page: nextPage }, await getNextPageData());
  }
}
function FunctionComponent() {
  const getNextPageData = asnyc () => {
    // (api 요청 로직..)

    // 만약 여기서 page상태를 변이하는 동작이 있는 경우
    // useEffect를 계속 실행하게 됨
    // page 변이 -> api 요청 -> page 변이 -> api 요청 ...
  };

  const handleChangePage = async (nextPage) => {
    setPage(nextPage);
    await getNextPageData();
  };

  useEffect(async () => {
    await getNextPageData();
  }, [page]);
}

Context api

context_api

클래스 컴포넌트는 하나의 Context를 구독할 수 있습니다. 그에 반해 함수 컴포넌트는 여러 Context를 구독할 수 있습니다. 만약 클래스 컴포넌트에서 여러개의 Context를 구독하고 싶다면 함수 컴포넌트로 전환하거나 활용해야합니다.

classcontexttype


사내 코드에서는 이러한 부분때문에 상태를 Context의 상태 데이터양보다 Props의 상태 데이터양이 더 많았습니다. 함수 컴포넌트로 전환하면서 관심사대로 Context를 묶어서 상태의 응집도를 높일 수 있었고, 이로 인해 Props drilling도 많이 줄어들게 되었습니다.


마무리

work_experience

클래스 컴포넌트를 사내에서 처음 마주하게 되어 많이 낯설었습니다. 하지만 함수 컴포넌트와 비교하면서 공부를 하다보니 금새 적응하고 코드를 작성할 수 있었습니다. 전환하는 과정에서 간혹 상태 변이 흐름을 전면 개선하는 작업이 있다보니 시간이 좀 더 걸리더라도 기존 기능 및 UI가 동일하게 유지하도록 조심해서 작업했습니다. 이러한 고생이 기쁨으로 마주할 때는 높아지는 전환율과 해당 코드를 유지보수하기 위해 다시 마주할 때 였습니다. 앞으로 클래스 컴포넌트 마이그레이션 작업을 맡게되면 많은 도움이 될 경험이었습니다.


참조

728x90

댓글