我想用交集观察器API实现动态分页,它按预期工作:向下滚动页面,获取新数据,但之后页面滚动到其开头.我知道发生这种情况是因为Reaction在加载新信息后重新呈现页面.但我能以某种方式阻止这一切吗?

以下是我的代码:


function AllUniversititesList() {
  const [loading, setLoading] = useState(false);
  const [listOfUnis, setListOfUnis] = useState([]);
  const [isSearched, setSearched] = useState(false);
  const lastElement = useRef();
  const observer = useRef();

  async function fetchAllUnis() {
    setLoading(true);
    const result = await SearchService.getAllUniversities(); //return of data from API
    setListOfUnis([...listOfUnis, ...result]);
    setLoading(false);
  }

  useEffect(() => {
    if(!listOfUnis.length) {
          fetchAllUnis();
    }
  }, [])

  useEffect(() => {
    if(loading) return;
    if(observer.current) observer.current.disconnect();
     const callback = (entries, observer) => {
      if(entries[0].isIntersecting) {
        fetchAllUnis()
      }
     }
     observer.current = new IntersectionObserver(callback);
     observer.current.observe(lastElement.current);
  }, [loading])

return (
    <section className='min-h-screen bg-slate-200 pt-[7%] '>
         {!loading && listOfUnis && listOfUnis.length > 0 &&  <UniversitiesList info = {listOfUnis}/>}
     <div className='w-full h-4' ref={lastElement}></div>
    </section>
  )
}

推荐答案

页面总是在顶部滚动的主要原因是,无论是否加载了某些数据,您都会有条件地呈现整个UnsitiesList组件.

为了避免这种情况,我建议对您的代码进行 struct 更改.将所有的观察者逻辑和状态放在unisitiesList组件中.这将允许您呈现新项目,而不会导致列表每次都在顶部滚动.

我刚才提到的示例实现如下所示:

function UniversititesList() {
  const [loading, setLoading] = useState(false);
  const [listOfUnis, setListOfUnis] = useState([]);
  const [isSearched, setSearched] = useState(false);
  const lastElement = useRef();
  const observer = useRef();

  async function fetchAllUnis() {
    setLoading(true);
    const result = await SearchService.getAllUniversities(); //return of data from API
    setListOfUnis([...listOfUnis, ...result]);
    setLoading(false);
  }

  useEffect(() => {
    if(!listOfUnis.length) {
          fetchAllUnis();
    }
  }, [])

  useEffect(() => {
    if(loading) return;
    if(observer.current) observer.current.disconnect();
     const callback = (entries, observer) => {
      if(entries[0].isIntersecting) {
        fetchAllUnis()
      }
     }
     observer.current = new IntersectionObserver(callback);
     observer.current.observe(lastElement.current);
  }, [loading])

  const renderUniList() {

   if(loading) {
    return <div>Is loading...</div>
   }

   if(!loading && listOfUnis.length === 0) {
    return <div>No data available...</div>
   }

   return listOfUnis.map((uni) => 
   // return your prefered jsx element here
   )
  }

return (
    <section className='min-h-screen bg-slate-200 pt-[7%] '>
     <div className="uni-list">
     {renderUniList()}
     </div>
     <div className='w-full h-4' ref={lastElement}></div>
    </section>
  )
}

Reactjs相关问答推荐

如何使用react-router-dom导航到网页中的其他路由?

无法使用Apollo客户端GraphQL设置Next.js 14

使用Thattle和Use Effect setTimeout进行搜索有什么不同

将动态元素中的输入数据传输到Reaction

捕获表单数据时的Reactjs问题

使用REACT-RUTER-DOM链接仅更新一个搜索参数

Antd V5组件自定义主题

如何管理可重用无线电输入的 React 状态?

如何根据用户在react.js中的 Select , Select 多个心形图标?

如何修改 react/jsx-no-useless-fragment 规则以允许 <>{children}

onChange in useEffect 的最佳实践

Suspense/Await - 解析数据加载/保存到状态后无限循环

需要先填写依赖输入字段,以便其他人工作

React Native PermissionsAndroid 不包括 READ_MEDIA_IMAGES.如何解决这个问题?

如何向 surveyjs 调查添加多个结尾?

如何使用react 路由将 url 参数限制为一组特定的值?

将 dict 值转换并插入到react 钩子的列表中

无法重用我的组件,它只显示 1 次

React 检测哪些 props 在 useEffect 触发器上发生了变化

如何将 id 从页面传递到另一个页面?