javascript - 反应:应用程序多次请求相同的端点
问题描述
我正在使用无限滚动组件。它正在工作,但它多次请求相同的端点(3 -4 次)。以我的 React 知识,让我解释一下发生了什么:
因为我设置了 initialLoad={true},所以 loadMore 函数将在组件渲染后立即调用。我可以设置initialLoad={false}但它不会在初始渲染中获取数据
- 在第一次渲染中,它调用loadMore函数 ==>加载状态改变 ==> 第二次渲染
- 在第二次渲染中,它调用loadMore函数 ==>跟踪状态更改 ==> 第三次渲染
- 在第三次渲染中,它调用loadMore函数 ==> 某些状态发生了变化 ==> 第四次渲染
索引.js
export default function index() {
const { tracks, error, loading, loadMore, hasMore } = usePublicTracks(
myApiEndPoint.TRENDING_TRACKS,
5,
);
return (
<div>
<Main>
<InfiniteScroll
initialLoad={true} //call loadMore function right after component rendered
pageStart={0}
loadMore={loadMore}
hasMore={hasMore}
>
<TrackList>
{tracks.map((track, i) => (
<TrackItem key={i}
track={track}
/>
))}
</TrackList>
{loading && hasMore && (
<div className="">
<Spin />
</div>
)}
</InfiniteScroll>
</Main>
</div>
);
}
使用PublicTracks.js
export const usePublicTracks = (endpoint, limit) => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [offset, setOffset] = useState('');
const [tracks, setTracks] = useState([])
const [hasMore, setHasMore] = useState(true);
console.log('tracks', tracks)
const loadMore = async params => {
try {
console.log('hello22222222222222222222222222222222222222222')
const res = await myApiAxiosInstance.get(endpoint, {
params: {
limit: limit,
lastVisible: offset
}
});
setLoading(false);
setTracks([...tracks, ...(res.data.collection)])
setOffset(res.data.lastVisible)
if (res.data.lastVisible == "end") setHasMore(false);
} catch (error) {
setLoading(false);
setError(error.message);
}
};
return {
error,
loading,
tracks,
loadMore,
hasMore
};
};
当我将 loadMore func 包装在useEffect中时,它显示错误Hooks can only be called inside of a function component. :
const loadMore = async params => {
useEffect(() => {
const loadMoreOnce = async () => {
//some logic
};
loadMoreOnce();
}, []);
};
我的问题是如何调用一次加载更多功能。然后每次滚动到窗口底部时调用它?如何防止多次请求同一个端点?
解决方案
const isLoading = false;
const myComponent = () => {
useEffect(() => {
loadMore(); // initial call, this useEffect equivalent to componentDidMount
}, []);
if (!isLoading && document.body.scrollTop >= document.body.offsetTop) {
console.log('loading, should see this once');
isLoading = true;
loadMore(); // here, after loadMore finished you need to resolve isLoading to false
}
return (<div>My component</div>);
}
尝试查找所有loadMore函数调用的调用,可能在其他地方也有调用,从页面开始更改偏移量,检查hasMore条件是否正确,因为几个调用也可能来自InfiniteScroll本身,当它认为你几次触底。
推荐阅读
- google-sheets - 使用 AND 和多个条件来格式化 google sheet/excel
- css - 适合父级的 Flex 盒子网格
- java - java列表的内存占用计算和GC计算
- python - 可变对象上的递归函数
- c# - 带有 Nuget 包的多个 Microsoft.Owin 版本
- php - 如何通过 MySql 查询结果中的循环输入表单(动态)发布 Ajax onClick
- amazon-web-services - 在 terraform 中创建 AWS 实例时如何使用 user_data url?
- php - 如何同步两个日期字段输入。一个漂移,需要一些指导
- python - pytest monkeypatch 终端大小
- c# - 如何编写没有根元素的碎片化 xml 文件?