Context API 최적화

홍범선·2024년 12월 27일
0

리액트

목록 보기
25/25

Context API

다음과 같이 지뢰찾기 페이지가 있습니다.

컴포넌트 구조는 다음과 같은데요.

Tr은 row의 개수, 즉 10개가 되구요

Td는 각 셀의 개수, 100개가 됩니다.

사실상 Props로 지뢰찾기의 필요한 데이터를 전달하는 것은 비효율적으로 보이는데요

그래서 Context API를 사용해봅시다.

MineSearch쪽을 Provider로 사용하면 다음과 같습니다.

	<TableContext.Provider value={value}>
      <Form />
      <div>{timer}</div>
      <Table />
      <div>{result}</div>
    </TableContext.Provider>

MineSearch 컴포넌트에서 timer state를 관리하여 1초마다 변경이 되는데요

그러면 Form 컴포넌트는 어떻게 될까요?

계속 렌더링이 됩니다.

Form 컴포넌트를 최적화 해봅시다.

const Form = memo(() => { ... }

React.memo를 사용하는 겁니다. React.memo는 이전 props와 현재 props를 비교하여 랜더링 여부를 결정하는데요.
지금은 props를 전달받는 것이 없으니 재랜더링이 되지 않겠네요
부모 컴포넌트와 독립적으로 작동하고, 컴포넌트 내부 state에만 의존하여 리렌더링이 발생합니다.




<TableContext.Provider value={value}>여기서 value값이 변하면 어떻게 될까요?

하위 모든 컴포넌트는 재렌더링이 됩니다.

MineSearch컴포넌트에서 timer로 인해 1초마다 재랜더링이 발생하는데요

이 때 value 자체는 변하지 않지만 새로운 value를 만들기 때문에 참조값이 바뀌어 버리는데요

그래서 100개나 있는 Td 컴포넌트들이 1초마다 재랜더링이 됩니다.


value자체를 메모리제이션하는 훅을 사용해야 하는데요

const value = useMemo(() => ({ tableData, halted, dispatch }), [tableData, halted]);

객체를 메모리제이션 할때에는 useMemo를 사용하면 됩니다.

의존성 배열값들이 변경되었을 때만 다시 계산하는데요.

그 결과 Td 컴포넌트는 timer로 인해 재렌더링 되는 현상을 막을 수 있습니다.




만약 cell을 눌렀을 때 모든 Td 컴포넌트가 재렌더링 될 필요가 있을까요?

필요한 부분만 랜더링 해주면 됩니다.

Td 쪽도 Cell data를 메모리 제이션 해주면 되는데요

const RealTd = memo(({ onClickTd, onRightClickTd, data}) => { ...}

onClickTd, onRightClickTd는 함수이기 때문에 useCallback으로 메모리제이션 해주었구요

data은 값이기 때문에 따로 해주지 않습니다.

Td 까지 최적화를 해주면 필요한 Td 컴포넌트만 랜더링 됩니다.

profile
알고리즘 정리 블로그입니다.

0개의 댓글