일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- parent padding
- 제어컴포넌트
- 리액트
- 조건부스타일
- transition
- CustomHook
- 문제해결
- tailwindCSS
- DOM
- debouncing
- BFC
- 화살표2개
- useQueryClient
- react
- BlockFormattingContext
- ?? #null병합연산자
- alias설정
- 서초구보건소 #무료CPR교육
- ㅡ
- es6
- ignore padding
- QueryClient
- 부모요소의 패딩 무시
- 부모패딩
- Carousel
- createPortal
- twoarrow
- 함수형프로그래밍
- accordian
- vite
- Today
- Total
프론트엔드 첫걸음
QueryClient 대신 useQueryClient 사용하는 이유 본문
[출처]
https://stackoverflow.com/questions/71540973/why-use-usequeryclient-from-react-query-library
https://tkdodo.eu/blog/react-query-fa-qs#why-should-i-usequeryclient
QueryClientProvider는 생성된 queryClient 를 React Context에 넣어 앱 전체에 배포한다. useQueryClient로 가장 잘 읽을 수 있다. 이렇게 하면 추가 구독이 생성되지 않으며 추가 재렌더링이 발생하지 않는다(클라이언트가 안정적인 경우).
//클라이언트가 안정적인 경우
export default function App() {
// ✅ this is stable
const [queryClient] = React.useState(() => new QueryClient())
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
//클라이언트가 안정적이지 않은 경우
export default function App() {
// 🚨 this is not good
const queryClient = new QueryClient()
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
이런경우엔 client를 prop으로 전달하지 않아도 된다. 아니면 client를 export하고 원하는 곳에서 import하면 된다.
exported-query-client
// ⬇️ exported so that we can import it
export const queryClient = new QueryClient()
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
hook 사용이 선호되는 몇가지 이유가 있다.
1: useQuery는 훅을 사용한다.
useQuery를 호출하면 내부적으로 useQueryClient를 호출한다.
이는 React Context에서 가장 가까운 클라이언트를 찾는 것을 의미한다. 큰 문제는 아니지만, import한 클라이언트가 컨텍스트 내의 클라이언트와 다른 클라이언트를 가져오는 경우 추적하기 어려운 버그가 발생할 수 있다. 이러한 상황을 피할 수 있다.
2: 앱과 클라이언트의 결합도를 낮춘다.
앱에서 정의한 클라이언트는 프로덕션 클라이언트다. 프로덕션에서 잘 작동하는 몇 가지 기본 설정이 있을 수 있다. 그러나 테스트에서는 다른 기본값을 사용하는 것이 좋을 수 있다. 예를 들어 테스트 중에 잘못된 쿼리를 시도하면 시간 초과로 테스트가 실패할 수 있기 때문에 테스트중에는 재시도 기능을 끄는 것(turning off retries)이 좋을 수 있다. (https://tkdodo.eu/blog/testing-react-query#turn-off-retries)
의존성 주입 메커니즘으로 사용할 때 React Context의 큰 장점 중 하나는 앱과 그 의존성 사이의 결합도를 낮출 수 있다는 것이다. useQueryClient는 위에 어떤 클라이언트가 있던지 상관하지 않고 사용할 수 있다. 프로덕션 클라이언트를 직접 가져온다면 이 장점을 잃게 된다.
3: 가끔 export 할 수 없을 때가 있다.
앱 컴포넌트 내에서 queryClient를 생성해야 하는 경우가 있다(위의 예시). 서버 측 렌더링을 사용하는 경우와 같이 다수의 사용자가 같은 클라이언트를 공유하지 않도록하려면 이렇게 한다.
마이크로프론트엔드를 사용할 때도 그렇다. 앱은 격리되어야 한다. 클라이언트를 앱 외부에서 생성하면 동일한 앱을 두 번 사용하면 동일한 페이지에서 클라이언트를 공유하게 된다.
마지막으로, queryClient의 기본값에 다른 hooks를 사용하려면 App 내에서 queryClient를 만들어한다. 예를 들어, 모든 실패한 mutation마다 토스트를 표시하는 전역 오류 핸들러가 있는 경우를 고려해보아라.
use-other-hooks
export default function App() {
// ✅ we couldn't useToast outside of the App
const toast = useToast()
const [queryClient] = React.useState(
() =>
new QueryClient({
mutationCache: new MutationCache({
// ⬇️ but we need it here
onError: (error) => toast.show({ type: 'error', error }),
}),
})
)
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
이렇게 queryClient를 만들 경우, 그냥 export하고 App에서 import해서 사용하는 것은 불가능하다.
네가 client를 export하고싶은 이유는 레거시 클래스 컴포넌트에서 쿼리 무효화를 수행해야 할 때일 것이며, 거기서는 훅을 사용할 수 없다. 그런 경우에 함수형 컴포넌트로 쉽게 리팩토링할 수 없다면, render props 버전을 만드는 것을 고려해라.
useQueryClient-render-props
const UseQueryClient = ({ children }) => children(useQueryClient())
usage
<UseQueryClient>
{(queryClient) => (
<button
onClick={() => queryClient.invalidateQueries({ queryKey: ['items'] })}
>
invalidate items
</button>
)}
</UseQueryClient>
useQuery나 다른 모든 hook에 대해서도 같은 방법을 사용할 수 있다.
useQuery-render-props
const UseQuery = ({ children, ...props }) => children(useQuery(props))
usage
<UseQuery queryKey={["items"]} queryFn={fetchItems}>
{({ data, isLoading, isError }) => (
// 🙌 return jsx here
)}
</UseQuery>
'개발 공부 > React' 카테고리의 다른 글
useLocation (0) | 2023.07.18 |
---|---|
[칼럼] React 컴포넌트를 커스텀 훅으로 제공하기 (0) | 2023.02.22 |
map으로 순회하는 component마다 ref 를 달 때 (0) | 2023.01.10 |
리액트 절대경로 사용하기 (0) | 2023.01.05 |
구글로그인 추가 (0) | 2022.10.20 |