-
상위에서 하위 함수들을 리프레쉬하는 로직 구하기Frontend/swr 2024. 9. 8. 22:47
앱 내에 당겨서 새로고침 기능을 구현해야될 일이 생겼다.
보통 당겨서 새로고침 기능은 상위 컴포넌트에서 UI로 노출될 일이 많다.
그러나 상위에서 모든 함수를 다 선언해서 하위로 props drilling을 해버리면 재렌더도 많아지고 부하가 커진다.
그렇기때문에 구현할 수 있는 여러 방법들이 있다.
1. 상위에서 함수 구현체 정의해놓고, 하위에서 함수 set하여 상위에서 실행시키기
이 방법은 어쩔 수 없이 구현체를 모두 props drilling을 하고, 리렌더 방지를 위해 ref로 감싸서 하위 컴포넌트에서 업데이트 함수를 set하는 방법이다.
이 방법의 장점은 상위 컴포넌트에서는 하위 컴포넌트에서 정해준 함수만 실행시키면 된다.
type UpdateFunc = (() => void) | undefined; type UpdateFuncs = { palmAmount: UpdateFunc; palmInfo: UpdateFunc; palmClaimable: UpdateFunc; }; export interface UpdateFuncProps { updateFuncsRef: MutableRefObject<UpdateFuncs>; } // 상위 컴포넌트 훅 내부에서 updateFuncsRef정의 const updateFuncsRef = useRef<UpdateFuncs>({ palmAmount: undefined; palmInfo: undefined; palmClaimable: undefined; }); // 하위 컴포넌트에 전달 <PalmAmount updateFuncsRef={updateFuncsRef} /> <PalmInfo updateFuncsRef={updateFuncsRef}/> <PalmClaimable updateFuncsRef={updateFuncsRef} /> // 각각의 하위 컴포넌트가 update 함수를 set export function PalmAmount(updateFuncsRef) { const { mutate } = useSWR( isFocused ? ["home-staking-info", address] : null, async () => { const res = await HomeStakingController.getPalmAmount(address); return res.data; } ); if (updateFuncsRef?.current) { updateFuncsRef.current.palmAmount = mutate; } return () } // 당겨서 새로고침 실행시 Object.values(updateFuncsRef.current).map((updateFunc) => updateFunc?.());
위와 같이 구성하면 하위 컴포넌트에서 함수만 set 해주면 되고 상위 컴포넌트에서는 저장된 함수가 있는 경우 모두 실행해주면 된다.
하지만, 위와 같은 방법은 업데이트할 함수가 추가될 때마다 props drilling을 해줘야 하는 번거로움이 있다.
어차피 어떤 함수를 리프레쉬할 지 안다면 다른 방법을 고안해볼 수 있다.
2. swr의 키를 직접 입력하여 mutate 시키기
swr은 기본적으로 key를 알면 해당 key에 저장되어있는 fetcher를 mutate 할 수있다.
그렇다 즉, key만 수집해서 업데이트 시키면 된다.
아래는 여러 API를 key과 각각이 구독하고 있는 값을 함께 반영하여 업데이트 하는 코드 최종본이다.
export function useRefreshInvestment() { const { blockNumber } = useBlockNumberStore(); const { address } = useActiveAddressStore(); const { chainID } = useActiveNetworkModel(); const keyList = [ ["palm-staking-open", chainID], ["palm-staking-info", chainID, blockNumber], ["palm-staked-amount", chainID, blockNumber, address], ["palm-claimable", chainID, blockNumber, address], ["home-staking-info", chainID, blockNumber, address], ["flex-info"], ]; const refreshInvestments = () => { keyList.forEach((key) => mutate(key)); }; return { refreshInvestments }; }
이렇게 사용하면 홈에서 refreshInvestments만 실행시켜주면 된다.
'Frontend > swr' 카테고리의 다른 글
swr을 이용하여 fetcher call 횟수를 효율적으로 줄이기 (0) 2024.09.08 isLoding, isValidating 차이, 첫 로드, 업데이트 로드 (0) 2024.09.08 여러 API 결과 한꺼번에 fetch해서 보여주기 (0) 2024.09.08