search

Home  >  Q&A  >  body text

Optimize data querying for React and React Query to only occur when the component is in the viewport

<p>I have a page that renders a list of post components using React, and for each post component I get the comments related to that post and display them inside using the React Query library. The problem is that when the user loads the post page, React Query loads all comments for all posts at once, which causes my backend to slow down. </p> <p>I want to implement a mechanism that only loads comments when the user scrolls to a specific post, instead of loading everything at once when the page renders. How to achieve this using React and React Query? </p> <p>This is my current sample code to get and display comments: </p> <p>My Post Component</p> <p> <pre class="brush:js;toolbar:false;">import React from 'react'; import { useQuery } from 'react-query'; const PostComponent = ({ post }) => { const { data, isLoading, error } = useQuery( ['comments', post.id], () => fetchComments(post.id) ); return ( <div> {/* Render your post component */} {isLoading && <div>Loading comments...</div>} {error && <div>Error getting comments</div>} {data && ( <div><p>{post.title}</p> </div> )} </div> ); };</pre> </p> <p>My Post Page Component <pre class="brush:js;toolbar:false;">import React from 'react'; import { useQuery } from 'react-query'; const PostsPage = () => { const { data, isLoading, error } = useQuery('posts', fetchPosts); return ( <div> {isLoading && <div>Loading posts...</div>} {error && <div>Error getting posts</div>} {data && data.map((post) => ( <PostComponent key={post.id} post={post} /> ))} </div> ); };</pre> </p>
P粉714890053P粉714890053443 days ago529

reply all(1)I'll reply

  • P粉323224129

    P粉3232241292023-08-29 15:51:44

    To achieve this goal, you need two components.

    1. Intersection Observer API - Used to determine if a component is in the viewport
    2. React Query Dependent Queries (enabled flag) - Enables the use of queries while the component is in the viewport
    To simplify interaction with the Intersection Observer API in your React app, you should use the useInView hook from the react-intersection-observer library .
    import React from 'react';
    import { useQuery } from "react-query";
    import { useInView } from "react-intersection-observer";
    
    const PostComponent = ({ post }) => {
      const { ref, inView } = useInView();
    
      const { data, isLoading, error } = useQuery(
        ["comments", post.id],
        () => fetchComments(post.id),
        // the useQuery hook will fetch only when inView is enabled
        { enabled: inView }
      );
    
      return (
        <div ref={ref}>
          {isLoading && <div>Loading comments...</div>}
          {error && <div>Error fetching comments</div>}
          {data && (
            <div>
              <p>{post.title}</p>{" "}
            </div>
          )}
        </div>
      );
    };

    reply
    0
  • Cancelreply