memo기능 버그3 - useMemo사용

noungheeya·2022년 11월 28일
0

project

목록 보기
7/10
post-thumbnail

메모기능 버그를 수정하려다 핀리스트 기능까지 수정하게 되었다.
변경한 메모가 화면에 렌더링 되지 않는 이유를 찾는 중 이해가지 않았던점이 invalidateQueries(['쿼리키'])를 통해 메모 변경 후 캐싱된 data를 stale상태로 바꿔주어 refetch가 일어나는데 왜 useQuery를 사용한 컴포넌트는 리렌더링 되면서 하위 컴포넌트는 리렌더링 되지 않는다는점이다.

Maintab(useQuery사용) > PinedListTab > PinedListBox

* 컴포넌트 순위

코드를 자세히 살펴보니 react-query의 문제도 아닌 그냥 아직은 전체적으로 컴포넌트를 구성하는 스킬이 부족해서 였던거 같다.

앞서 react원리에 맞지 않게 state를 활용하지 못했던것 처럼 Maintab에서 state에 컴포넌트를 담았고 아무리 리패치 되더라도 useState통한 변경이 아님으로 기본값이 아닌 컴포넌트들은 리렌더링 되지 않는다.

MainTab컴포넌트 내에서 하위컴포넌트들은 tab리스트를 클릭했을때 clickTab함수를 통해 setState가 실행되어 리렌더링 된다.
즉 리패치 되더라도 getQueryData를 통해 해당 데이터를 받아온 핀리스트 및 메모기능의 화면구성이 바뀌지 않았다.

좀 더 구조를 한눈에 보기 위해 그림으로 그려보면![]

ReserableBox는 저장된 쿼리키에 데이터에 존재하면 pin아이콘 색이 주황색이 되고
PinedListBox는 저장된 쿼리키에 데이터가 ui구조를 통해 화면에 나타난다.

ReservableTab수정

상태변화 분석

  • ReservableTab과 관련된 부분에서 상태가 변화는것은 pin아이콘 상태이다.
  • clickEvent가 발생했을때 pinedList를 삭제 및 추가하며 바로 서버에 변경된 list를 post하거나 delete한다.
    즉, pin 아이콘은 서버에서 받아온 데이터 변화에 영향을 받는다.

코드구조


ReservableTab

  • getQueryData를 통해 저장된 쿼리에 캐싱된 핀리스트data를 가져온다(①)
  • 캐싱된 data에 핀리스트에 list가 존재를 나타내는 boolean값을 prop을 통해 ReserVableBox컴포넌트에 전달한다.(②)

ReservableBox

  • 상위컴포넌트에서 받아온 boolean값을 pinState 초기값에 할당하고 그 값을 바탕으로 렌더링 한다
  • pin아이콘을 클릭했을땐 useState를 통해 pinedState를 변경하고 그값에 따라 post및 delete한다.

ui변화는 단순하지만 코드가 상당히 복잡하다..ㅠㅠ

변경후


pin아이콘은 fetchData에 영향을 받기 때문에 useState를 과감히 지워버리고 상위컴포넌트에서 전달받는 값도 지워버렸다

상위 컴포넌트가 PinedListBox하위컴포넌트에서 getQUeryData를 통해 캐싱된 데이터를 받아오고 바로 그값을 바탕으로 pin아이콘 상태를 보여줬다.
클릭을 했을때 isPined상태에 따라 post 및 delete를 함으로서 refetch가 일어나기때문에 자동으로 pin아이콘상태가 바뀐다.

그런데.. 만약 데이터가 많아지면 비효율적인 렌더링이 발생할 거 같다. pin하나만 바꾸거나 메모기능에서도 메모하나만 수정했는데 refetch가 일어남으로서 전체가 리렌더링 된다.
이를 해결하는 방법이 무엇이 있을까 생각한다 useMemo를 떠올랐다.
list중 바뀐 항목의 컴포넌트만 렌더링이 발생하는것이다.
*콘솔을 찍어보면 모든 항목이 리렌더링된다

React.memo사용하기


props에서 변경된 값이 존재해야 하기 때문에 상위에서 다시 쿼리값을 가져왔다.

하위컴포넌트에 메모제이션을 함으로서 isPined값이 변경된 컴포넌트만 렌더링이 발생한다!

그러나 영상에서는 MainTab컴포넌트에서 PinedListTab만 반환하도록 하여 가능했다. 다시 원래코드로 바꾼다면 화면구조가 바뀌지 않는다.
그래서 어차피 PinedListTab 컴포넌트와 ReservableTab 컴포넌트는 별개의 컴포넌트가 될 수 밖에 없고 렌더링 최적화를 위해 react-query의 장점을 활용하여 useQuery를 MainTab이 아닌 각각의 컴포넌트에서 사용하고 각 변화가 있는 리스트만 렌더링 될 수 있게 rect.memo를 사용하였다.

성능최적화를 위한 useMemo기능을 언제 사용하는지 감이 안왔는데 드뎌 사용했다!!👍👍

profile
귀여븐 엥팁이지롱😊

0개의 댓글