【发布时间】:2020-01-04 10:27:17
【问题描述】:
我正在尝试在 react 中使用交叉点观察器来实现无限滚动,但我面临的问题是,在交叉点观察器的回调中,我无法读取当前“页面”和“列表”的最新值,所以我可以获取下一页的数据。
import ReactDOM from "react-dom";
import "./styles.css";
require("intersection-observer");
const pageSize = 30;
const threshold = 5;
const generateList = (page, size) => {
let arr = [];
for (let i = 1; i <= size; i++) {
arr.push(`${(page - 1) * size + i}`);
}
return arr;
};
const fetchList = page => {
return new Promise(resolve => {
setTimeout(() => {
return resolve(generateList(page, pageSize));
}, 1000);
});
};
let options = {
root: null,
threshold: 0
};
function App() {
const [page, setPage] = useState(1);
const [fetching, setFetching] = useState(false);
const [list, setlist] = useState(generateList(page, pageSize));
const callback = entries => {
if (entries[0].isIntersecting) {
observerRef.current.unobserve(
document.getElementById(`item_${list.length - threshold}`)
);
setFetching(true);
/* at this point neither the 'page' is latest nor the 'list'
*they both have the initial states.
*/
fetchList(page + 1).then(res => {
setFetching(false);
setPage(page + 1);
setlist([...list, ...res]);
});
}
};
const observerRef = useRef(new IntersectionObserver(callback, options));
useEffect(() => {
if (observerRef.current) {
observerRef.current.observe(
document.getElementById(`item_${list.length - threshold}`)
);
}
}, [list]);
return (
<div className="App">
{list.map(l => (
<p key={l} id={`item_${l}`}>
{l}
</p>
))}
{fetching && <p>loading...</p>}
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
当前行为: 'page' 和 'list' 的值始终等于初始状态,而不是最新值。第 2 页后无限滚动不起作用
预期行为:在回调函数中,它应该读取状态“页面”和“列表”的更新值。
这是这个demo的工作沙箱https://codesandbox.io/s/sweet-sun-rbcml?fontsize=14&hidenavigation=1&theme=dark
【问题讨论】:
-
而不是
observerRef.current = new IntersectionObserver(callback, options);,observerRef.current = new IntersectionObserver((entries) => callback(entries, page, fetching, list), options);并相应地更新callback方法签名怎么样? (设置方法很好,只有值作为参数包含) -
没什么区别
标签: javascript reactjs react-hooks