React/RTKQuery:useLazyQuery无法强制重新获取数据问题
问题分析
你遇到的核心问题有两个:
- 参数更新异步延迟:dispatch更新Redux状态是异步操作,你调用
triggerGetPostsQuery时,组件还没完成重新渲染,UserIDParam和page还是更新前的旧值,导致查询用了旧参数,直接命中缓存。 - 强制刷新选项用错:RTK Query里没有
preferCacheValue这个配置项,你需要用forceRefetch: true来强制忽略缓存发起新请求。
解决方案
1. 直接传递最新参数,绕开Redux更新延迟
点击按钮时,不要依赖useSelector返回的旧状态,直接构造最新的参数值传入查询:
- 点击“我的帖子”时,直接用
userID生成新的userIdParam,page固定为1; - 点击“显示全部帖子”时,直接用空字符串作为
userIdParam,page取localStorage里的旧值。
2. 用正确的强制刷新选项
调用triggerGetPostsQuery时,传入{ forceRefetch: true },这个配置会强制RTK Query发起新请求,同时新的响应会自动更新缓存,完全符合你“只在点击时强制刷新,保留正常缓存机制”的需求。
修改后的完整代码片段
import * as React from 'react'; import Box from '@mui/material/Box'; import Avatar from '@mui/material/Avatar'; import Menu from '@mui/material/Menu'; import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import Logout from '@mui/icons-material/Logout'; import { useNavigate } from 'react-router-dom'; import LocalPostOfficeIcon from '@mui/icons-material/LocalPostOffice'; import './ProfileButton.css'; import {useSelector, useDispatch} from 'react-redux'; import {updateUserIDParam, updatePageParam} from '../../../features/Params'; import {useLazyGetPostsQuery} from '../../../services/PostsApi'; export default function ProfileButton() { const dispatch = useDispatch(); const sort = useSelector((state) => state.Params.value.sort); const [triggerGetPostsQuery] = useLazyGetPostsQuery(); const userID = localStorage.getItem('userID'); const userName = localStorage.getItem('userName'); const [anchorEl, setAnchorEl] = React.useState(null); const open = Boolean(anchorEl); const handleClick = (event) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; const myPostsButtonOnClick = () => { const newUserIdParam = `id=${userID}`; const newPage = 1; // 更新Redux状态 dispatch(updateUserIDParam(newUserIdParam)); localStorage.setItem("OldPageValue", useSelector(state => state.Params.value.page)); dispatch(updatePageParam(newPage)); // 用最新参数发起强制刷新查询 triggerGetPostsQuery({ page: newPage, sort, UserIDParam: newUserIdParam }, { forceRefetch: true }); } const showAllPostsButtonOnClick = () => { const newUserIdParam = ""; const oldPageValue = Number(localStorage.getItem("OldPageValue")); // 更新Redux状态 dispatch(updateUserIDParam(newUserIdParam)); dispatch(updatePageParam(oldPageValue)); // 用最新参数发起强制刷新查询 triggerGetPostsQuery({ page: oldPageValue, sort, UserIDParam: newUserIdParam }, { forceRefetch: true }); localStorage.removeItem("OldPageValue"); } // 补全组件原有渲染代码(Menu、Avatar等) }
补充说明
如果你的PostsApi定义了缓存标签(比如providesTags: ['Posts']),也可以通过dispatch(PostsApi.util.invalidateTags(['Posts']))让缓存失效,之后的查询会自动重新获取数据。但如果没法用标签,上面的方法是最直接有效的。
内容的提问来源于stack exchange,提问作者user17402771
相关产品推荐
相关产品推荐

