bkdragon's log

React-Query useQuery를 Hook으로 사용하기 본문

React

React-Query useQuery를 Hook으로 사용하기

bkdragon 2023. 5. 2. 23:58

웹 페이지를 만들다보니 똑같은 데이터를 여러곳에서 패칭해야하는 경우 생겼다. 그래서 useQuery를 이용한 데이터 패칭을 훅으로 만들어서 사용하려고 한다.

 

React-Query는 캐싱을 지원하기 때문에 중복해서 요청해도 캐싱되어 있는지를 먼저 확인함으로 필요없는 요청이 늘어나는 걱정은 하지 않아도 된다.

 

userId와 accessToken을 이용한 유저 데이터 상세 데이터를 패칭하는 훅을 만들것이다. 이름은 useUser라고 하겠다.

import { useQuery } from "react-query";
import { SERVER_URL } from "@/util/constant";

import * as Apis from "picktogram-server-apis/api/functional";
import { isBusinessErrorGuard } from "picktogram-server-apis/config/errors";

export default function useUser(userId : number | null, token : string | null) {
    const fetchUser = async (userId : number | null, token : string | null) => {
        try {
            if(!token  || !userId) {
                return
            }
            const response = await Apis.api.v1.users.getDetailProdfile({
                host : SERVER_URL as string,
                headers : {
                    Authorization : token
                }
            },
                userId
            )

            if(isBusinessErrorGuard(response)) {
                return
            }

            return response.data
        } catch (error) {
            console.log(error)
        }
    }


    return useQuery(['getUser', userId, token], () => fetchUser(userId, token))
}

 (fetchUser 내부의 내용은 몰라도 된다. Nestia SDK를 이용한 통신 방법인데 추후에 포스트를 추가하거나 추가 설명을 첨부하겠다.)

 

useQuery 자체를 return 하는 형태이다.

 

이렇게 만든 훅을 특정 컴포넌트에서 사용할텐데 사용하는 코드를 간략하게 살펴보자.

export default function Header() {
  const token = useRecoilValue(tokenState)
  const myId = useRecoilValue(myIdState)

  const {data : userDetail} = useUser(myId, token )
  const [nickName, setNickName] = useState<string>('')

  useEffect(() => {
    if(userDetail?.nickname){
      setNickName(userDetail.nickname)
    }
  }, [userDetail?.nickname])


  return (
    <div>
    	{nickName}
        {/* ...생략 */}
    </div>    
  )
}

 

token과 userId는 recoil을 통한 전역 상태로 관리하고 있다. 이 두 상태를 useUser에 넣고 사용한다. token과 userId는 리액트 자체의 상태와 똑같이 동작한다.(값이 변하면 컴포넌트가 재렌더링 = 코드가 다시 실행) 

 

nickname이라는 추가적인 상태를 만든 이유는 Next의 Hydration Error을 방지하기 위함이다.

 

token과 userId가 전역 상태임으로 굳이 매개변수로 받지 않고 hook 내부에서 불러와서 사용할 수 있겠다고 생각할 수 있다. 헌데 hook 내부에서 token과 userId를 불러오면 로그인 시 token이 저장이 안되는 에러가 발생한다. 이유는 정확하게 모르겠다.

 

 

'React' 카테고리의 다른 글

커링과 HOC  (0) 2023.05.31
[React-Query] 캐싱, 헷갈리는 부분  (0) 2023.05.26
컴포넌트 분리하기 전략  (0) 2023.05.24
[React Query] select  (0) 2023.03.11
[React Query] refetchOnMount  (0) 2023.03.04