32일차(React Query)

Undong·2023년 5월 6일
0

항해구구

목록 보기
32/52
post-thumbnail

32일차

오늘은 리액트 쿼리에 대해서 공부를 하였다..

React Query

리액트 쿼리를 처음 보았을 때 어떤 라이브러리 감이 잡히지 않았다. 알고 보니 서버의 값을 클라이언트에 가져오거나, 캐싱, 값 업데이트, 에러핸들링 등 비동기 과정을 더욱 편하게 하는데 사용되는 라이브러리이다.

즉 React Query는 React 애플리케이션에서 데이터를 관리하기 위한 라이브러리이다. 이 라이브러리를 사용하면 서버에서 가져온 데이터를 캐시하여 필요할 때 즉시 사용할 수 있으며, API 호출 및 상태 관리를 자동으로 처리한다. 이러한 기능으로 인해 React Query를 사용하면 복잡한 데이터 관리 코드를 작성하지 않고도 데이터를 쉽게 가져오고 업데이트할 수 있다.

React Query는 기본적으로 React Hooks와 함께 작동한다. 사용자가 데이터를 가져와야 할 때, React Query는 캐시에 저장된 데이터를 반환하거나 API 호출을 수행하여 새 데이터를 가져온다. 이렇게 가져온 데이터는 캐시에 저장되며, 데이터가 변경될 경우 자동으로 업데이트된다. 또한, React Query는 오래된 데이터를 자동으로 삭제하여 캐시 메모리를 최적화한다

React Query는 다양한 기능을 제공한다. 예를 들어, 캐시된 데이터를 무효화하거나, 데이터를 무한 스크롤링하면서 가져오는 것과 같은 고급 기능을 제공한다. 또한, React Query는 다양한 상태에 대한 강력한 오류 처리 및 다양한 데이터 소스에 대한 지원을 제공한다.

React Query를 사용하면 코드가 간결해지고, 성능도 향상된다. 따라서, React 애플리케이션에서 데이터 관리를 위한 라이브러리를 찾고 있다면, React Query는 좋은 선택일 수 있다.

useQuery

데이터를 get 하기 위한 api이다. post, update는 useMutation을 사용한다.
첫번째 파라미터로 unique Key가 들어가고, 두번째 파라미터로 비동기 함수(api호출 함수)가 들어간다. (당연한 말이지만 두번째 파라미터는 promise가 들어가야한다.)
첫번째 파라미터로 설정한 unique Key는 다른 컴포넌트에서도 해당 키를 사용하면 호출 가능한다. unique Key는 string과 배열을 받는다. 배열로 넘기면 0번 값은 string값으로 다른 컴포넌트에서 부를 값이 들어가고 두번째 값을 넣으면 query 함수 내부에 파라미터로 해당 값이 전달된다.
return 값은 api의 성공, 실패여부, api return 값을 포함한 객체이다.
useQuery는 비동기로 작동한다. 즉, 한 컴포넌트에 여러개의 useQuery가 있다면 하나가 끝나고 다음 useQuery가 실행되는 것이 아닌 두개의 useQuery가 동시에 실행된다. 여러개의 비동기 query가 있다면 useQuery보다는 밑에 설명해 드릴 useQueries를 권유드린다.
enabled를 사용하면 useQuery를 동기적으로 사용 가능하다.

const Todos = () => {
  const { isLoading, isError, data, error } = useQuery("todos", fetchTodoList, {
    refetchOnWindowFocus: false, // react-query는 사용자가 사용하는 윈도우가 다른 곳을 갔다가 다시 화면으로 돌아오면 이 함수를 재실행합니다. 그 재실행 여부 옵션 입니다.
    retry: 0, // 실패시 재호출 몇번 할지
    onSuccess: data => {
      // 성공시 호출
      console.log(data);
    },
    onError: e => {
      // 실패시 호출 (401, 404 같은 error가 아니라 정말 api 호출이 실패한 경우만 호출됩니다.)
      // 강제로 에러 발생시키려면 api단에서 throw Error 날립니다. (참조: https://react-query.tanstack.com/guides/query-functions#usage-with-fetch-and-other-clients-that-do-not-throw-by-default)
      console.log(e.message);
    }
  });

  if (isLoading) {
    return <span>Loading...</span>;
  }

  if (isError) {
    return <span>Error: {error.message}</span>;
  }

  return (
    <ul>
      {data.map(todo => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  );
};

useMutation

값을 바꿀때 사용하는 api이다. return 값은 useQuery와 동일하다

import { useState, useContext, useEffect } from "react";
import loginApi from "api";
import { useMutation } from "react-query";

const Index = () => {
  const [id, setId] = useState("");
  const [password, setPassword] = useState("");

  const loginMutation = useMutation(loginApi, {
    onMutate: variable => {
      console.log("onMutate", variable);
      // variable : {loginId: 'xxx', password; 'xxx'}
    },
    onError: (error, variable, context) => {
      // error
    },
    onSuccess: (data, variables, context) => {
      console.log("success", data, variables, context);
    },
    onSettled: () => {
      console.log("end");
    }
  });

  const handleSubmit = () => {
    loginMutation.mutate({ loginId: id, password });
  };

  return (
    <div>
      {loginMutation.isSuccess ? "success" : "pending"}
      {loginMutation.isError ? "error" : "pending"}
      <input type="text" value={id} onChange={e => setId(e.target.value)} />
      <input
        type="password"
        value={password}
        onChange={e => setPassword(e.target.value)}
      />
      <button onClick={handleSubmit}>로그인</button>
    </div>
  );
};

export default Index;

마무리

이렇게 기본적인 리액트 쿼리에 대해서 공부해보았다. 다양한 면에서 편리하게 사용할 수 있는 리액트 쿼리에 대해서 많이 안 것 같아 좋았다. ❤️

profile
console.log("Hello")

0개의 댓글