리액트 컴포넌트 재사용 메커니즘와 tanstack query 캐싱 메커니즘
문제해결 | | 5분 읽기

문제
상품 조회 테이블에서 판매설정/전시상태 샐랙트 박스가 이전(검색 결과 직전 혹은 이전 페이지) 상태 값 참조하는 문제
문제 원인
판매설정 및 전시 상태에서 상태를 컴포넌트 내부에서 직접 관리하게 되면서 검색 시에 이전 행들의 데이터가 남는 문제 발생
컴포넌트 마운트 시에만 초기값 설정되고 컴포넌트가 재사용되면서 이전 행의 상태가 그대로 남게 됨
해결 방안
상태 제거 및 직접 참조로 변경하여 서버(테이블) 데이터 직접 사용
판매설정/전시상태 수정 시 캐시 무효화로 데이터 리프레시
의문사항
- 데이터를 새로 불러오는데 왜 이전 상태를 기억하고 있는지?
- 캐싱된 데이터를 쓰기 때문에 이전 상태를 기억하는 것 같은데 네트워크 탭에 왜 데이터 패칭 기록이 남는지?
- 왜 unmount 안되는지?
React의 컴포넌트 재사용 메커니즘
SaleSettingSelect이나IsDisplayedSelect내부에 지역 상태가 있고- 같은 컴포넌트가 같은 위치에 계속 렌더링되면 내부(지역) 상태가 유지됨
- 테이블 row의 key가 동일(
row.id= index와 동일한 값)하므로, 데이터가 변경되어도 해당 위치의 컴포넌트는 언마운트되지 않고 리렌더링만 발생(재사용)하여 내부 useState가 초기화되지 않음 (props의 업데이트와 상관없이) - 초기값은 컴포넌트가 최초 마운트될 때만 사용됨
- 테이블 row의 key가 동일(
tanstack query의 캐싱 메커니즘
- 데이터가 패칭되지만 캐싱된 데이터를 쓰는 이유
- 데이터를 새로 불러올 때
console.log(isLoading, isFetching);에서 콘솔 찍힌게false true에서false false로 바뀜- 이미 캐시된 데이터가 있는 상태에서 백그라운드로 새로운 데이터를 fetch하고 있다는 뜻
- staleTime이 0(기본값)인 경우, 캐시는 사용되지만 백그라운드에서 데이터를 새로고침하기 위한 HTTP 요청이 전송됩니다.(공식 깃허브) (swr 캐시전략)
→ StaleTime: The duration until a query transitions from fresh to stale. As long as the query is fresh, data will always be read from the cache only - no network request will happen! If the query is stale (which per default is: instantly), you will still get data from the cache, but a background refetch can happen under certain conditions.
→ IfstaleTime == 0__, the cache will be used but an HTTP request will be sent to refresh the data.
It will happen "in background"', cause UI will typically stay the same unless you rely onisFetchingin some way.- 캐시에 이미 데이터가 있는 경우에도 새로운 쿼리 인스턴스가 마운트되면 캐시 데이터를 즉시 반환하면서 동시에 새로운 네트워크 요청을 트리거합니다 (공식문서)
→ A second instance of
useQuery({ queryKey: ['todos'], queryFn: fetchTodos })mounts elsewhere.
Since the cache already has data for the ['todos'] key from the first query, that data is immediately returned from the cache.
The new instance triggers a new network request using its query function.