useEffect 대신 useMemo를 사용한 이유

이승훈·2023년 7월 2일
0

0. 문제 상황

import Markdown from 'react-native-markdown-display';

interface Props {
 Prop들
}

const SomethingComponent = ({Prop들}: Props) => {

  const customRules = {
      text: (node: any) => {
        Very complex and time consuming
    }

  return (
    <Markdown customRules={customRules}>{summary}</Markdown>
  );
};

export { SomethingComponent };

리액트 네이티브 어플리케이션에서 Markdown을 보여주는 Markdown 컴포넌트는 customRules라는 속성을 받을 수 있으며 이 customRules를 통해서 MarkDown 컴포넌트 내부의 텍스트에 어떠한 효과를 줄 수 있다.

이 customRule을 설정해주지 않았을 땐 아무 문제가 없었지만 customRules를 지정해준 뒤
컴포넌트가 리렌더링 될 때 마다 1.5초 가량의 딜레이가 발생하였고 이는 유저에게 답답함을 느끼게 할것이 자명했다.

1. 원인

이 SomethingComponent는 다른 부모 컴포넌트에 종속되어있는 자식 컴포넌트이며 그로인해 부모컴포넌트가 리렌더링 될 때 마다 customRules가 다시 계산되는 현상이 발생하였다.

불행히도 customRules는 계산과정이 비교적 복잡하였고 이러한 계산과정을 렌더링 할 때 마다 반복하게되니 딜레이가 발생하였다.

2. 해결 방안

2-1. useEffect, useState를 사용

import Markdown from 'react-native-markdown-display';

interface Props {
 Prop들
}

const SomethingComponent = ({Prop들}: Props) => {
   const [customRules, setCustomRules] = useState<{
    text: (node: any) => JSX.Element;
  }>();

  useEffect(() => {
    setCustomRules({
      text: (node: any) =>{
        Very complex and time consuming
      });
  }, []);

  return (
    <Markdown customRules={customRules}>{summary}</Markdown>
  );
};

export { SomethingComponent };

customeRules를 state로 관리하고 SomethingComponent가 처음 렌더링 될 때만 계산될 수 있도록 의존성배열에 빈배열을 설정한 useEffect안에서 setCustomRules를 통해 customRules 값을 설정해주었다.

이렇게되면 SomethingComponent의 부모 컴포넌트의 state가 변경되어 리렌더링이 발생하여도 customRules가 매번 재계산되는 일이 없으니 딜레이 현상이 사라지게 되었다.

2-2. useMemo 사용

import Markdown from 'react-native-markdown-display';

interface Props {
 Prop들
}

const SomethingComponent = ({Prop들}: Props) => {

  const customRules = useMemo(
    () => ({
      text: (node: any) => {
        Very complex and time consuming
      },
    }),
    [someDependency],
  );
  return (
    <Markdown customRules={customRules}>{summary}</Markdown>
  );
};

export { SomethingComponent };

useMemo를 사용한 경우는 간단하다.
useMemo훅을 사용하여 첫 렌더링 시 복잡한 계산의 결과를 메모이징 하여 이후에는 의존성배열안에 있는 값이 변경되지 않는한 재계산이 되지 않도록 코드를 작성하였다.

2-3. useMemo를 채택한 이유

  1. 렌더링 횟수
  • useState와 useEffect를 사용한 경우

  • useMemo를 사용한 경우

useStatem, useEffect를 사용할 시 초기 setState를 함으로서 컴포넌트를 한번 더 렌더링 하게 된다.
컴포넌트의 1회 렌더링 횟수가 대단히 큰 영향을 끼치진 않았지만 그래도 굳이 필요없는 연산과정을 반복할 필요는 없다고 판단하였따.

  1. 코드 가독성 및 유지 보수성

useMemo를 사용한 경우 그냥 useMemo를 쓰니까 메모이징을 했구나 그리고 메모이징한 값은 customRules구나 그리고 이 customRules가 MarkDown의 속성으로 들어가는구나라고 코드가 위에서 아래로 쭉 읽히며 이해가 되었다.

그러나 useEffect와 useState를 사용할 경우 state를 파악해야 하며 useEffect안의 연산내용을 다시 파악하는 등 코드내용을 파악하는데 스크롤을 여러번 올렸다 내렸다 할 필요가 생겨 내용 이해가 비교적 어렵다고 판단하였다.

3. 결론

사실 뭐 큰 차이가 있다고 생각하진 않는다.
허나 악마는 디테일에 있고 이러한 작은 차이들이 모여 큰 차이를 만든다고 생각하기에 이러한 과정을 뿌듯하게 느끼고 있다.
그럼 이번주도 끗.

profile
Beyond the wall

0개의 댓글