React Query 사용해보기

황세훈·2024년 8월 27일

cmc 프로젝트

목록 보기
5/10
post-thumbnail

React Query 사용해보기

API 통신

axios instance 정의

const axiosInstance = axios.create({
  baseURL: `${SERVER_URL}`,
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${JWT_TOKEN}`,
  },
  timeout: 1000,
});

useMutation

블로그 참고하여 진행
React-Query를 이용해 서버에 변경 작업 요청 시 사용 (get 제외)

type 정의

export interface AgeRequest {
  year: number;
  month: number;
}

export interface AgeResponse {
  code: number;
  message: string;
}

mutationFn 정의

export async function patchAgeData(data: AgeRequest): Promise<AgeResponse> {
  const response = await axiosInstance.patch<APIResponse<AgeResponse>>('/register/age', data);
  console.log(response.data);
  return response.data;
}

query key 작성
아직 정확한 용도를 모르겠음 ( 더 공부해야할 부분 )

const ageKeys = {
  all: ['age'] as const,
  info: () => [...ageKeys.all, 'info'] as const,
  detail: () => [...ageKeys.all, 'detail'] as const,
  list: (page: number) => [...ageKeys.all, 'list', page] as const,
};

함수 작성

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';

export function useAgeMutation() {
  const queryClient = useQueryClient();

  const mutation = useMutation({
    // mutation에는 querykey를 작성하지 않는다.
    mutationFn: (data: AgeRequest) => patchAgeData(data),
    onSuccess: (newData) => {
      // ['age', 'detail']인 캐시 업데이트
      queryClient.setQueryData(ageKeys.detail(), newData);

      // 연관된 GET요청을 update
      // GET요청을 다시 보내면 POST요청 후에 GET요청이 무조건 발생. 따라서 불필요한 GET 대신 메모리상의 쿼리에 데이터를 업데이트.
      //   queryClient.setQueryData(ageKeys.all, () => {
      //     isAgeCheck: false;
      //   });
    },
    onError: () => {
      console.error('useAgeMutation 에러 발생');
    },
  });

  return { ageMutation: mutation };
}

컴포넌트에서 활용

import { useAgeMutation, AgeRequest } from '@apis/insueboarding/insueboarding';

function Complete({ birthYear, birthMonth, gender, insures }: CompleteProps) {

const { ageMutation } = useAgeMutation();
  
const handleAPI = () => {
  
    const updateAgeData: AgeRequest = {
      year: birthYear,
      month: birthMonth,
    };
    ageMutation.mutate(updateAgeData);
 };

  useEffect(() => {
    //api
    handleAPI();
  }, []);
  
return( ... )

}

if ) useMutate를 통해 서버로 부터 받은 response값을 받고 싶다면

const postQuestion = () => {
    //api
    const questionData: plannerPOSTRequest = {
      quesion: text,
      isShare: check,
      insuranceType: convertInsureType(insureSearchCategory) as string, 
    };
  
    insuePlannerMutation.mutate(questionData, {
      onSuccess: (data) => {
        console.log('API 호출 성공:', data);  // 이렇게 가져오면 된다.
      },
      onError: (error) => {
        console.error('API 호출 실패:', error);
      },
    });
  };

useQuery

react query를 통해 get 통신을 하고 싶다면 useQuery를 통해서 활용할 수 있음

query 정의

// GET QuestionTitle
async function getQuestionTitle() {
  const { accessToken } = useStore.getState();
  const response = await axiosInstance.get<APIResponse<QuestionTitleData>>('/quesion', {
    headers: {
      Authorization: `Bearer ${accessToken}`,
    },
  });
  return response.data.data;
}

export function useGetQuestionTitleQuery() {
  const query = useQuery<QuestionTitleData>({
    queryKey: questionTitleKeys.detail(),
    queryFn: getQuestionTitle,
  });
  return { questionTitleQuery: query };
}

query 사용 1 (상태값에 넣으면서 사용하고 싶을 때 )

const { questionTitleQuery } = useGetQuestionTitleQuery();
const [history, setHistory] = useState<QuestionTitle[]>([]);

useEffect(() => {
    // 최초 실행 시 히스토리 목록 조회
    if (questionTitleQuery.isFetched) {
      setHistory([...(questionTitleQuery.data ?? [])].reverse() as QuestionTitle[]);
    }
  }, [questionTitleQuery.isFetched, questionTitleQuery.isRefetching]); // isRefetching도 추가해주어서 post후 invalidateQueries 되었을 때, 다시 초기화하는 과정 트래킹

query 사용 2 ( 상태값에 넣지 않고 사용 )

태그에 직접 넣어서 사용

	<QList>
          {questionQuery.data?.pages.map((page, pageIndex) =>
            page.content.map((q, index) => (
              <QuestionAnswer key={`${pageIndex}-${index}`} question={q.question} answer={q.answer} tags={q.links} />
            )),
          )}
        </QList>
        {questionQuery.isFetching && (
            <Loading type={'spinningBubbles'} color={'#6879FB'} width={69.33} height={69.33} />
        )}

참고자료

https://velog.io/@kandy1002/React-Query-%ED%91%B9-%EC%B0%8D%EC%96%B4%EB%A8%B9%EA%B8%B0

https://musma.github.io/2023/09/14/react-query.html

https://velog.io/@rgfdds98/React-Query-queryKeys

profile
음.. 한줄로는 부족하다

0개의 댓글