React-query 시리즈 파트 3: useQuery 후크로 데이터 가져오기.

Cover image by Lawrence Eagles in the article: What’s new in React Query 3



안녕하세요 여러분 👋

나는 다시 돌아왔다. 격려에 항상 감사드립니다. 긴 시간을 내어 이 시리즈를 읽어주신 💖에 감사드립니다. 나의 새로운 추종자들에게; 고맙습니다! 실망시키지 않도록 최선을 다하겠습니다.

2부에서 react-queryqueries 둘 다에 대한 사용자 지정 기본값을 설정하여 mutations 와 함께 제공되는 일부 기본값을 재정의하는 방법에 대해 이야기했습니다. retry , staleTime , cacheTime , refecthOnMountqueries 에 대해 retrymutations 에 대해 몇 가지 다른 옵션과 같은 옵션에 사용자 정의 기본값을 설정했습니다.

목차


  • Intro

  • The useQuery hook
  • Fetching data
  • Passing variables to query functions
  • Overriding query defaults

  • Conclusion

  • 소개

    In this part, we will be learning how to fetch data from an API using the useQuery hook. I promised to show you how we can override the defaults we set earlier, so we will have a look at that too. Always remember to use the table of contents above to jump to sections relevant to you.

    useQuery 후크

    We start by installing axios 비트 리팩토링.

    npm i axios
    


    우리QueryClient는 새 파일./src/util/queryClient.js로 이동합니다.

    import { QueryClient} from 'react-query';
    
    const queryClientConfig = {
        defaultOptions: {
          queries: {
            retry: 2,
            staleTime: 1000 * 30,// 30 seconds
            cacheTime: 1000 * 30, //30 seconds
            refetchOnMount: "always",
            refetchOnWindowFocus: "always",
            refetchOnReconnect: "always",
            refetchInterval: 1000 * 30, //30 seconds
            refetchIntervalInBackground: false,
            suspense: false,
    
          },
          mutations: {
            retry: 2,
          },
        },
    
     export const queryClient = new QueryClient(queryClientConfig);
    
    


    여기까지 왔다면 이 스니펫을 설명했습니다.

    우리는 App.js 따라서

    import { QueryClientProvider } from 'react-query';
    import { ReactQueryDevtools } from 'react-query/devtools';
    import { queryClient } from "./util/queryClient";
    
    
     function App() {
       return  (
               <QueryClientProvider client={queryClient}>
                 {/* The rest of your application */}
                 <ReactQueryDevtools initialIsOpen={false} />
               </QueryClientProvider>
            )
     }
    

    queryKeys.js./src/util/queryKeys.js 파일도 생성합니다.
    이 파일은 애플리케이션에 대한 모든 쿼리 키를 호스팅합니다.

    export const fetchPostsKey = "FETCH_POSTS";
    

    fetchPosts.service.js에서 ./src/services/fetchPosts.service.js 파일을 만들고 게시물 목록을 가져오는 간단한 비동기 함수를 만듭니다.
    이 데모에서는 JSONPlaceholder REST API를 사용할 것입니다.

    import axios from "axios";
    
    /**
     * @desc fetch a list of posts
     */
    export const fetchPosts = async () => {
      const res = await axios.get(`https://jsonplaceholder.typicode.com/posts`);
      return res?.data;
    };
    


    데이터를 가져 오는 중

    Create a Posts.js component at ./src/components/Posts.js

    Remember to import your Posts.js component to your App.js

    ...
    
     function App() {
       return  (
                <QueryClientProvider client={queryClient}>
                  <Posts/>
                  <ReactQueryDevtools initialIsOpen={false} />
                </QueryClientProvider>
            )
     }
    

    Posts.js

    import { useQuery } from "react-query";
    import { fetchPosts } from "../../services/fetchPosts.service";
    import { fetchPostsKey } from "../../util/queryKeys";
    
    const Posts = () => {
    
      const {  isLoading, isError, isSuccess, refetch, remove, data, error} = useQuery(fetchPostsKey, fetchPosts);
    
    
      return (
        <div>
          {isLoading ? (
            <div>Loading...</div>
          ) : isError ? (
            <div>An error while fetching posts</div>
          ) : (
            data?.map((post) => (
              <div key={post?.id}>
                <div>{post?.title}</div>
                <div>{post?.body}</div>
              </div>
            ))
          )}
        </div>
      );
    };
    export default Posts;
    

    The useQuery hook accepts a query key as its first argument and the query function as its's second argument.
    The query key is required, the query function also is required as there was not default query function defined for our queries in QueryClient . Let's take a quick brush at the items in the destructured object useQuery returns to us.

    isLoading : It is a boolean value that returns true when the query has no data and is currently fetching and false when not.

    isError : Also a boolean value. It return true when the query attempt results in an error.

    isSuccess : Returns true if the query has received a response with no errors and is ready to display its data. isSuccess is false when query is not yet resolved or results in an error.

    refetch : This is a function that manually refetches the query.

    remove : This function is used to manually remove the query from cache.

    data : It is the response from the last successful query. data will be undefined if query fails for the first time.

    error : It is the error response from your query. It is defined when your query is in an isError state.

    The useQuery hook returns more values in the destructured object than described here, but this few I chose for the scope of this article. You can read more about the useQuery hook here .

    쿼리 함수에 변수 전달

    So, what if you want to pass a variable or variables to your query function? E.g. you have a function that fetches a single post and it requires you to pass in a post id ; What do you do?
    Let's see how it is done.

    We will a new key entry in a queryKeys.js file at ./src/util/queryKeys.js .

    ...
    export const fetchSinglePostKey = "FETCH_SINGLE_POST";
    

    Create also a fetchSinglePost.service.js file at ./src/services/fetchSinglePost.service.js and create your simple async function to fetch a single post by id .

    fetchSinglePost.service.js

    import axios from "axios";
    
    /**
     * @desc fetches a single post
     */
    export const fetchSinglePost = async ({queryKey}) => {
    const [_key, id] = queryKey
    const res = await axios.get(`https://jsonplaceholder.typicode.com/posts/${id}`);
      return res?.data;
    };
    

    Post.js

    import { useQuery } from "react-query";
    import { fetchSinglePost } from "../../services/fetchSinglePost .service";
    import { fetchSinglePostKey } from "../../util/queryKeys";
    
    const Post = () => {
    
    // fetching the post with the id of 1
    
      const {  isLoading, isError, isSuccess, refetch, remove, data, error} = useQuery([fetchSinglePostKey, 1], fetchSinglePost );
    
    
      return (
        <div>
          {isLoading ? (
            <div>Loading...</div>
          ) : isError ? (
            <div>An error while fetching post</div>
          ) : (
              <div >
                <div>{data?.title}</div>
                <div>{data?.body}</div>
              </div>
            )
          )}
        </div>
      );
    };
    export default Post;
    

    Here, we are no more using a string value for our query key but an array , passing in the query string first and the post id as required by our query function fetchSinglePost.service.js .

    The fetchSinglePost function declared in useQuery hook is passed in a context, this context has queryKey array nested in it. This queryKey array contains your query string as the first item in the array and your id variable for fetching our single post.

    Remember to import your Post.js component to your App.js

    ...
    
     function App() {
       return  (
                <QueryClientProvider client={queryClient}>
                   ...
                  <Post/>
                  <ReactQueryDevtools initialIsOpen={false} />
                </QueryClientProvider>
            )
     }
    

    쿼리 기본값 재정의

    We have seen two demonstrations using useQuery but don't forget that they all are operating within the queries default we set earlier. To override some of the global configurations, we pass an object as a third argument to the useQuery hook. Every option you declare a new value, that option is overridden for that useQuery instance only.

    ...
     const {  isLoading, isError, isSuccess, refetch, remove, data, error} = useQuery([fetchSinglePostKey, 1], fetchSinglePost, {
        refetchInterval : 3* 1000 //3 seconds
    });
    
    ...
    

    What this snippet above implies is that, although we configured react-query globally to refetch queries every 30 seconds, This particular query will refetch every 3 seconds; breaking away from the global configurations.

    결론

    The returned data from our queries are persisted in a cache. In the next part, we will discuss how the to interact with this cache.
    Thank you all for your support. If you are beginner and haven't written something, do that today! Please give me a 💖 if this post or part of it has helped you. Comments are welcomed too.
    Follow me on

    목차


  • Intro

  • The useQuery hook
  • Fetching data
  • Passing variables to query functions
  • Overriding query defaults

  • Conclusion
  • 좋은 웹페이지 즐겨찾기