文章目录
- 问题描述
- 解决思路
- 引发的问题
- 优化后的代码
问题描述
ios端手机下的h5/小程序,滚动到底部时加载更多数据,但是滚动到底部时重复触发加载事件,在安卓机下则不会发生该问题,记录一下解决方案。
解决思路
为了防止下拉事件重复触发,对下拉事件做一次防抖处理:
import { useState, useRef, useCallback } from 'react';
import debounce from 'lodash/debounce';const paramPageRef = useRef(1)
const [searchResult, setSearchResult] = useState([]);// 防抖查询const debounceSearch = useCallback(debounce(() => handleSearch (), 300),[],);// 接口查询数据const handleSearch = async () => {const params = {// 一些参数county: selectedArea.regionName,address: searchKey,...stableParams,currentPage: paramPageRef.current,};try {const res = await fuzzySearchByPage(params);console.log('addressSearch---response-->', res);if (res.currentPage === 1) {setSearchResult(res?.records || []);} else { setSearchResult([...searchResult, ...res?.records]);} setHasMore(res.hasMore )paramPageRef.current += 1} catch (err) {console.error('handleSearch----err--->', err);}};<ScrollRefreshdown={false}pull={false}Lower={() => {if (hasMore) {debounceSearch(data)} ;}}/ >
引发的问题
以上代码解决了重复触发下拉到底的问题,但是使用useCallBack的防抖会形成闭包,导致在 handleSearch 方法中取不到最新的 searchResult, 从而加载更多时会少加载前一页的数据,为了防止这个闭包问题,可以通过设置一个新的state,,通过监听这个state触发handleSearch方法。
优化后的代码
import { useState, useRef, useCallback } from 'react';
import debounce from 'lodash/debounce';const paramPageRef = useRef(1)
const [searchResult, setSearchResult] = useState([]);
const [page, setPage] = useState(1);// 防抖查询const debounceSearch = useCallback(debounce(() => setPage(paramPageRef.current), 300),[],);useEffect(()=>{console.log(page)if (page !==1 ) {handleSearch()}},[page])// 接口查询数据const handleSearch = async () => {const params = {// 一些参数county: selectedArea.regionName,address: searchKey,...stableParams,currentPage: paramPageRef.current,};try {const res = await fuzzySearchByPage(params);console.log('addressSearch---response-->', res);if (res.currentPage === 1) {setSearchResult(res?.records || []);} else { setSearchResult([...searchResult, ...res?.records]);} setHasMore(res.hasMore )paramPageRef.current += 1} catch (err) {console.error('handleSearch----err--->', err);}};<ScrollRefreshdown={false}pull={false}Lower={() => {if (hasMore) {debounceSearch()} ;}}/ >
如此便可以正常请求了,下拉事件在300毫秒内只会触发一次。