首页  >  问答  >  正文

优化React和React Query的数据查询,仅在组件在视口中时进行

<p>我有一个使用React渲染帖子组件列表的页面,对于每个帖子组件,我都会获取与该帖子相关的评论,并使用React Query库将其显示在内部。问题是,当用户加载帖子页面时,React Query会一次性加载所有帖子的所有评论,这会导致我的后端变慢。</p> <p>我想实现一个机制,只有当用户滚动到特定的帖子时才加载评论,而不是在页面渲染时一次性加载所有内容。如何使用React和React Query实现这一点?</p> <p>这是我当前的示例代码来获取和显示评论:</p> <p>我的帖子组件</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> {/* 渲染你的帖子组件 */} {isLoading && <div>正在加载评论...</div>} {error && <div>获取评论时出错</div>} {data && ( <div><p>{post.title}</p> </div> )} </div> ); };</pre> </p> <p>我的帖子页面组件 <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>正在加载帖子...</div>} {error && <div>获取帖子时出错</div>} {data && data.map((post) => ( <PostComponent key={post.id} post={post} /> ))} </div> ); };</pre> </p>
P粉714890053P粉714890053391 天前497

全部回复(1)我来回复

  • P粉323224129

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

    为了实现这个目标,您需要两个组件。

    1. Intersection Observer API - 用于确定组件是否在视口中
    2. React Query Dependent Queries(enabled标志)- 在组件在视口中时启用查询的使用
    为了简化在React应用中与Intersection Observer API的交互,您应该使用来自react-intersection-observer库的useInView钩子。
    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>
      );
    };

    回复
    0
  • 取消回复