antd-mobile 的infinitescroll组件带搜索案例出错,如何解决?

  const [gasTrajectoryData, setGasTrajectoryData] = useState([])
  const [qpNo, setQpNo] = useState("")
  const [hasMore, setHasMore] = useState(true)
  const [currentPage, setCurrentPage] = useState(1)
  const pageSize = 10
  useEffect(() => {
     loadMore()
  }, [])

  const onSearch = async () => {
    setCurrentPage(1)
    setGasTrajectoryData([])
    setHasMore(true)
    await loadMore()
  }

  const loadMore = async () => {
    try {
      const response = await apiClient.get(
        `/qpsf/airBottleData/${currentPage}/${pageSize}/?qpNo=${qpNo}`
      )
      if (response.data.data.length === 0) {
        setHasMore(false) // 没有数据
      } else {
        setGasTrajectoryData([...gasTrajectoryData, ...response.data.data])
        setCurrentPage(currentPage + 1)
      }
    } catch (error) {
      console.error("Error fetching data:", error)
    }
  }

照着官网的InfiniteScroll 组件实现带搜索的无限滚动,但是在搜索时出现了一点小问题,第一次点击搜索时,没有数据,再点击一次后数据就有了,打开控制台发现currentPage是旧值导致搜不到

img

加了await和延迟几秒都没用,不知道该怎么解决了

从你提供的代码来看,它应该能够正常工作。然而,我无法直接看到你的完整代码,所以只能给出一些通用的建议。

  1. 确保你的 apiClient.get 函数正确处理请求,并且服务器返回的数据格式正确。例如,服务器应该返回一个对象,其中包含一个名为 "data" 的属性,该属性包含你要的数据。
  2. 确保你在调用 setGasTrajectoryData 函数时,新的数据已经被添加到旧的数据后面。你的代码已经这样做了,但是要确保 gasTrajectoryData 是一个数组,并且你的服务器返回的数据也可以被合并到数组中。
  3. 确保你在搜索时正确地传递了查询参数 qpNo。你可以在 apiClient.get 函数的URL中打印出来,看看是否正确。
  4. 如果你的问题与异步操作有关,尝试使用 useRef Hook 来存储异步操作的结果。这可以帮助你更好地理解异步操作何时完成。
  5. 最后,确保你的组件已经正确地挂载,并且所有的状态变量和函数都可以被访问到。

如果这些建议都不能解决你的问题,我建议你提供更多的代码和错误信息,这样我可以更具体地帮助你。

【以下回答由 GPT 生成】

问题原因:

问题的原因在于 onSearch 函数中调用了 loadMore 函数,而 loadMore 函数是一个异步函数。在 onSearch 函数中,立即调用 loadMore 函数后,setCurrentPage(1) 的执行需要等待,而 loadMore 函数立即执行,此时 currentPage 的值还是旧值。因此,第一次搜索时无法得到正确的数据。

解决方案:

为了解决这个问题,我们需要确保在调用 loadMore 函数之前,currentPage 已经更新为新值。可以通过将 loadMore 函数的调用放在 setCurrentPage(1) 的回调函数中来实现。

修改代码如下:

const onSearch = () => {
    setCurrentPage(1, async () => {
        setGasTrajectoryData([]);
        setHasMore(true);
        await loadMore();
    });
}

这样,在调用 setCurrentPage 后,将回调函数作为参数传递,确保 setCurrentPage 的更新已经完成后再执行后续操作。

请注意,根据你提供的代码,setCurrentPage 函数应该是同步函数,不需要使用 await。因此,在修改后的代码中,可以去掉 await 关键字。

此外,也可以在 loadMore 函数之前加上一些校验,防止无法正确获取数据时继续加载。

修改代码如下:

const loadMore = async () => {
    try {
        const response = await apiClient.get(
            `/qpsf/airBottleData/${currentPage}/${pageSize}/?qpNo=${qpNo}`
        );
        if (response.data.data.length === 0) {
            setHasMore(false); // 没有数据
        } else {
            setGasTrajectoryData([...gasTrajectoryData, ...response.data.data]);
            setCurrentPage(prevPage => prevPage + 1);
        }
    } catch (error) {
        console.error("Error fetching data:", error);
    }
}

setCurrentPage 的回调函数中,使用回调函数的形式更新 currentPage 的值,确保当前的 currentPage 是正确的上一次的 currentPage 加 1 的值。

请注意,这里使用了 prevPage => prevPage + 1 的箭头函数形式来更新 currentPage 的值,确保在更新时使用的是最新的值。

希望以上解决方案能够解决你的问题。如果还有其他问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^