javascript - useEffect 中的 IntersectionObserver 只工作一次
问题描述
我正在使用反应和交叉点观察者 api 构建一个无限滚动应用程序。
但我被困在intersectionObserver 只有一次在useEffect 中的部分。
这是代码
import React, { useState, useEffect, createRef } from 'react';
import axios from 'axios';
function App() {
const [page, setPage] = useState(1);
const [passengers, setPassengers] = useState([]);
const bottomRef = createRef();
const scrollCallback = (entries) => {
if (entries[0].isIntersecting) {
axios.get(`https://api.instantwebtools.net/v1/passenger?page=${page}&size=10`).then(res => setPassengers(prevState => [...prevState, ...res.data.data]));
}
};
useEffect(() => {
const observer = new IntersectionObserver(scrollCallback, {
root: null,
threshold: 1,
});
observer.observe(bottomRef.current);
return () => {
observer.disconnect();
}
}, [bottomRef]);
return (
<div className="container">
<div className="lists">
{
passengers.map((passenger, idx) => {
const { airline, name, trips } = passenger;
return (
<div className="list" key={idx}>
<h4>User Info</h4>
<p>name: {name}</p>
<p>trips: {trips}</p>
<h4>Airline Info</h4>
<p>name: {airline.name}</p>
<p>country: {airline.country}</p>
<p>established: {airline.established}</p>
<p>head quarter: {airline.head_quarters}</p>
<p>website: {airline.website}</p>
</div>
)
})
}
</div>
<div ref={bottomRef} />
</div>
);
}
当滚动到达底部时,scrollCallback
useEffect 中的函数可以将两个数组合并为一个,并最终显示我想要查看的合并数据。
然而,这只工作一次。useEffect 生命周期不再起作用。所以我改为observer.disconnect();
但是observer.unobserve(bottomRef.current);
这发生了一个错误说
TypeError: Failed to execute 'unobserve' on 'IntersectionObserver': parameter 1 is not of type 'Element'.
为什么useEffect
生命周期无法读取bottomRef
?
工作代码示例:https ://codesandbox.io/s/dazzling-newton-jvivj?file=/src/App.js
奇怪的是codeandbox中的代码有效
解决方案
如果你可以observe
参考,你当然unobserve
也可以,只要你有正确的、相同的参考。
useEffect(() => {
const observer = new IntersectionObserver(scrollCallback, {
root: null,
threshold: 1,
});
const {current} = bottomRef;
observer.observe(current);
return () => {
observer.unobserve(current);
};
}, [passengers]);
这永远不会说current
不是节点。
此外,如果发生了变化passengers
,您最好保留该引用,而不是保留永远不会改变的东西,因为bottomRef
它是current
包装器,但它不会“永远”改变,而passengers
状态一旦相交就会改变。
交替地
由于bottomRef
不打算改变,您也可以只观察该节点而从不清理它的观察。
useEffect(() => {
const observer = new IntersectionObserver(scrollCallback, {
root: null,
threshold: 1,
});
observer.observe(bottomRef.current);
}, [bottomRef]);
无论哪种方式都应该解决问题。
推荐阅读
- html - 如何在不滚动主体滚动条的情况下在带有滚动条的 div 中使用 focus() 来聚焦 id
- python - 输入包含 NaN、无穷大或对于 dtype('float64') 错误而言太大的值,但数据集中没有值
- java - 在eclipse中导出项目只导出.classpath和.project
- reactjs - 具有大量图像的视图的 React Native 渲染性能
- ios - iOS SDK Shopify:更改集合中产品的排序顺序
- java - 如何使用私有 mib 获得 snmptrap v2 的响应
- php - AWS S3 cp 命令手动工作,但不适用于 crontab
- python - matplotlib 使用 adjustText 对文本进行 y 调整
- xpath - XPATH,返回特定 div 中的特定元素
- java - Spock spring模块在运行测试时导致NoSuchMethodError