React Query Key 변경

밥하는중·2022년 7월 21일
0

React

목록 보기
2/5
post-thumbnail

React Query를 처음 사용할 때 Key에 대한 고민을 깊게 하지 않은 상태로 시작했다.

그러다보니 이런식으로 사용 했다

유저의 이름을 검색하면 입력 할 때마다 결과를 list로 목록을 그리는 useQuery 이다

export const useFetch = (key: any, method: string, url: string, param?: any, option?: any) => {
    return useQuery<any, AxiosError, IResult>(key, () => fetchFn(method, url, param), {
        ...option
    });
}
 useFetch(['getUserNm', deboundStr], 'get', `/usr/search/${deboundStr}`, null, {
        onSuccess: (res: IResult) => {
            if (res.result === Consts.SUCCESS) {
                setOnUserNmList(true);
            }
        },
 });

처음엔 ['getUserNm', deboundStr] 이런식으로 사용하다가 검색화면에서 검색필터가 5개 이상인 페이지는 어떻게 해야하나 고민이였다.

그래서 변경한게 검색필터를 Array로 만들어서 넣었다

['getUserNm', filters]

filters는 [키워드, 셀렉트박스선택값, 셀렉트박스선택값2,..., 페이지번호, 한페이지에 보여줄 Row수]

그런데 이렇게 하다보니 또 문제가 생겼다.

Array의 몇번째 인덱스가 어떤 검색조건값인지 기억해야하고 Key Array에 순서가 달라지면 새로운 Query로 인식한다는거다.

그래서 Object로 변경했다.


//asis filters = ['','Y','1','30'] 

//to-be
const filters:IFilters = {
	keyword: '', // 검색어
  	useYn: 'Y', // 사용여부 셀렉트박스
  	page:1, // 페이지 번호
  	pagePerRow: 30, // 한 페이지에 보여줄 row
}

그런데 여기서 문제가 2개가 더 있어서 해결했다.

  1. 검색조건의 onChange에 filters에 set을 하고 있어서
    검색이 바로바로 되는것이였다.
    검색버튼을 눌렀을 때만 검색이 되어야하니 state를 하나 더 만들었다.
    input이나 SelectBoxon에 Change를 담는 state는 filters를 이용하고 query key에는 fetchKeys라는 state를 만들어서 검색버튼을 클릭했을 때 setFetchKeys를 이용해서 새롭게 fetch를 진행했다.
    ['getUserNm', fetchKeys]

  2. query keys의 이름에 규칙성이 없었다.
    그러다보니 나중에 useMutation 후에 onSuccess 콜백에서queryClient.invalidateQueries(지정한key) 할 때 key의 규칙성이 필요했다.
    그러다가 이 블로그를 봤다

https://tkdodo.eu/blog/effective-react-query-keys

정독 한번 하고 바로 변경했다.

export const Userkeys = {
    all: ['user'] as const,
    lists: () => [...Userkeys.all, 'list'] as const,
    list: (filters: IFilters) => {
        return [...Userkeys.lists(), filters] as const
    },
    details: () => [...Userkeys.all, 'detail'] as const,
    detail: (id: string) => [...Userkeys.details(), id] as const,
};
useFetch(Userkeys.list(filters),'get', url, config)

Factory를 통해 키를 생성하니 키의 규칙성이 생기고
(오타방지, 네이밍고통해방)
invalidateQueries를 할 때도 user 의 모든 query를 무효화한후에 다시 불러올수도 있고 user의 특정 query만 할 수 도 있다.

모든 user 의 query 무효화 invalidateQueries(['user'])
user 목록만 무효화 invalidateQueries(['user','list'])

setQueryData를 써도 되지만 데이터종류도 많고 fetch후에 callback에서 해야할 작업이 많아서 invalidateQueries를 사용했습니다

#Ref
https://react-query-v3.tanstack.com/guides/query-invalidation
https://tkdodo.eu/blog/effective-react-query-keys

profile
공통기능으로 요령피우자

0개의 댓글