Typescript로 투두리스트로 만들면서 각 단계별로 기능들을 하나씩 추가해나가면서 만들어 나가는 과제 중에 redux를 이용해서 구현을 하는 단계에서 고민이 하나 생겼다.
todo 상태값과 관련된 로직들은 reducer(/modules/todo/todoSlice.ts)에서 관리하고 dispatch나 selector같은 내용들은 커스텀 훅(/hooks/useTodos.ts)에서 관리를 할 수 있도록 코드를 작성하였다.
이 중에서 useTodos는 다음과 같이 구현했다.
위 코드에서 가장 마음에 걸리는 코드는 32번 ~ 39번줄이었다.
useTodos가 호출이 될 때마다 해당 코드는 실행이 될텐데 지금이야 괜찮은데 데이터량이 많아지면 조금 무리하는거 아닐까? 라는 생각이 들어서 다음과 같은 생각을 했다.
일단 크게는 2가지를 생각했고, 결국에는 useMemo와 부모에서 내려주는 2가지 방법을 다 사용을 했다.
위와 같이 구현했을 때 뭐 사실 달라질게 없었다고 느껴져서 튜터님을 찾아뵈어 질문을 드렸고 튜터님이 나의 생각을 유도를 해주셨는데 a 컴포넌트와 b 컴포넌트에서 useTodos를 호출을 하면 결국 useTodos는 2번 실행이 되는 것이다. 그러면 결국 useMemo또한 다시 한번 실행이 되는 것일 뿐, useMemo가 불필요 하다는 점이었다.
그것 뿐만 아니라 애초에 useTodos는 todos에 의존하고 있고 또 그것밖에 없기 때문에 당연하게도 todos가 바뀐다면 다시 계산을 해야하는 작업이기 때문에 할 필요가 없다
내 생각에 리액트에서 최적화라는 것은 불필요한 랜더링을 막는 것의 의미가 제일 클 것 같다. 불필요한 랜더링과 필요한 랜더링이라는게 처음에는 단순 양으로만 따졌던 것 같은데 다양한 관점에서 불필요한 랜더링이 무엇인지에 대해서 생각해보는 관점을 가져야겠다.