Optimize data querying for React and React Query to only occur when the component is in the viewport
P粉714890053
P粉714890053 2023-08-28 17:26:18
0
1
539
<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粉714890053
P粉714890053

reply all(1)
P粉323224129

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>
  );
};
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template