RTK Query中if语句未按预期工作的问题求助
问题分析及解决方案
核心问题
- 逻辑运算符错误:你使用了按位与
&而非逻辑与&&,导致条件判断不符合预期。 - 普通变量无法触发组件更新:
simplesData是普通变量,不是React状态,修改它不会触发组件重渲染,且组件每次渲染时都会被重置为空数组。 - RTK Query状态同步问题:调用
getSimples(0).unwrap()后,isSuccess和data的更新是异步的,此时直接判断isSuccess条件不会成立。
修正后的代码
import { Box, Stack, Skeleton } from "@mui/material"; import React, { useEffect, useState } from "react"; import Post from "../components/postComponent"; import { useGetSimplesMutation } from '../services/authApi' const Feed = () => { const [getSimples, { isLoading }] = useGetSimplesMutation() // 用React状态存储累积数据,支持无限滚动 const [simplesData, setSimplesData] = useState([]) // 记录当前偏移量,用于加载更多时传递给后端 const [offset, setOffset] = useState(0) // 防止重复触发加载更多请求 const [isLoadingMore, setIsLoadingMore] = useState(false) // 统一的加载数据逻辑 const fetchSimples = async (currentOffset) => { setIsLoadingMore(true) try { // 直接获取请求成功的数据,无需依赖RTK Query的异步状态 const newData = await getSimples(currentOffset).unwrap() // 合并新旧数据 setSimplesData(prev => [...prev, ...newData]) // 更新偏移量,为下次加载做准备 setOffset(prev => prev + newData.length) } catch (error) { console.error(error.message) } finally { setIsLoadingMore(false) } } // 初始加载数据 useEffect(() => { fetchSimples(0) }, []) // 滚动到底部触发加载更多(可根据需求替换为Intersection Observer等方案) useEffect(() => { const handleScroll = () => { const isNearBottom = window.innerHeight + document.documentElement.scrollTop >= document.documentElement.offsetHeight - 100 if (isNearBottom && !isLoadingMore) { fetchSimples(offset) } } window.addEventListener('scroll', handleScroll) return () => window.removeEventListener('scroll', handleScroll) }, [offset, isLoadingMore]) return ( <Box flex={6} p={{ xs: 0, md: 2 }}> {/* 初始加载时的骨架屏 */} {isLoading && simplesData.length === 0 && ( <Box marginLeft={3}> <Stack spacing={1} > <Skeleton variant="text" height={100} /> <Skeleton variant="text" height={20} /> <Skeleton variant="text" height={20} /> <Skeleton variant="rectangular" height={300} /> </Stack> </Box> )} {/* 渲染已加载的帖子列表 */} {simplesData.map(simples => ( <div key={simples._id}> <Post userName={simples.userName} dateSubmitted={simples.dateSubmitted} beforePic={simples.beforePic} afterPic={simples.afterPic} tag={simples.tag} /> </div> ))} {/* 加载更多时的骨架屏 */} {isLoadingMore && ( <Box marginLeft={3}> <Stack spacing={1} > <Skeleton variant="text" height={100} /> <Skeleton variant="text" height={20} /> <Skeleton variant="text" height={20} /> <Skeleton variant="rectangular" height={300} /> </Stack> </Box> )} </Box> ); }; export default Feed;
关键修改说明
- 将
simplesData改为React状态,确保数据修改后触发组件重渲染,且不会在组件更新时丢失。 - 直接使用
unwrap()返回的请求结果,避开RTK Query状态更新的异步延迟问题。 - 添加
offset状态记录当前加载位置,配合后端实现分页加载。 - 新增
isLoadingMore状态,防止滚动时重复发起请求。 - 补充了滚动触发加载更多的示例逻辑,可根据实际需求替换为更优雅的监听方案(如Intersection Observer)。
内容的提问来源于stack exchange,提问作者DocSJ1980
相关产品推荐
相关产品推荐

