RTK 查询挂钩 - 防止在 arg 更改时轮询自动重新获取
我试图刷新查询挂钩中的令牌,每 9 秒使用轮询功能:
"/App.tsx"
..
...
const [storedToken, setStoredToken] = useState(getStoredToken());
const { data, error, refetch } = useRefreshUserQuery(storedToken, {
pollingInterval: 9000,
// refetchOnMountOrArgChange: false // -> This has no effect
});
...
..
问题是,当使用 setStoredToken(token) 设置令牌时,它会立即重新获取。新令牌作为参数传递给查询钩子 storedToken
并立即重新获取(就像无限循环)。
能够做到这一点就太好了。有没有更好的方法通过轮询刷新令牌?
I'm trying to refresh a token in a Query hook, with the polling feature every 9 seconds:
"/App.tsx"
..
...
const [storedToken, setStoredToken] = useState(getStoredToken());
const { data, error, refetch } = useRefreshUserQuery(storedToken, {
pollingInterval: 9000,
// refetchOnMountOrArgChange: false // -> This has no effect
});
...
..
The problem is, it re-fetches instantly when the token is set with setStoredToken(token). The new token is passed as argument to the Query hook storedToken
and refetch immediately (like an infinite loop).
That would be pretty neat to be able to do this. Is there any better way to refresh a token with polling?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信这个问题在 RTK-Q 级别上没有什么需要解决的 - 这是钩子和渲染生命周期架构的一个非常常见和预期的“限制”。我觉得 RTK-Q 轮询不符合您的要求,当然,您正在努力实现 - 它实际上不是常识中的轮询。至少 - 它是条件轮询,需要更多的逻辑)
所以我会通过 debouncing 和 useEffect 来解决这个问题:
useEffect
内容和data
内容可能不同,但总体而言想法应该很清楚。useDebounce 来自 https://www.npmjs.com/package/use-debounce ,
但如果您已经定义了一些实现,那么您自己的实现应该工作相同。
另一个想法,稍微触动你的 AUTH 设置 - 就是
完全避免这部分,并保持
useRefreshUserQuery()
不带参数。最有可能和常见的是将令牌存储在
localStorage
或 redux\other 存储中,并基于将设置标头的fetchBaseQuery
定义新的baseQuery
和/或包含带有credentials: "include"
的 cookie,以及来自localStorage
或 redux\other 存储的令牌。当然,您需要在第一次 AUTH 期间存储它。我认为 RTK-Q auth 示例也以某种方式揭示了这种情况:
https ://redux-toolkit.js.org/rtk-query/usage/examples#authentication
在你避免使用
useState
和查询钩子参数之后 - 你将能够使用轮询没有问题:I believe that issue is nothing to solve on RTK-Q level - it's a pretty common and expected "limitation" of hooks and rendering lifecycle architecture. And I feel that RTK-Q polling just won't fit your requirements here, of course, that you are trying to achieve - it's not actually polling in common sense. At least - it's conditional polling, which needs some more logic)
So I would solve this just by debouncing and useEffect:
The
useEffect
content anddata
content may differ, but the overall idea should be clear.useDebounce is from https://www.npmjs.com/package/use-debounce,
but your own implementations should work the same if you have some defined already.
Another idea, touching you AUTH setup a bit - is just avoid
the part at all, and keep
useRefreshUserQuery()
without params.Most likely and common is to store the token in
localStorage
or redux\other store, and define newbaseQuery
, based onfetchBaseQuery
that will set header and\or to include cookies withcredentials: "include"
with a token fromlocalStorage
or redux\other store. Definitely, you will need to store it during the first AUTH then.I think RTK-Q auth example reveals this case in some way also:
https://redux-toolkit.js.org/rtk-query/usage/examples#authentication
After you'll avoid that
useState
and query hook param - you'll be able to use polling with no issues:这里的“轮询”意味着“在获得数据后 X 秒获取”,但是当然您必须获取第一个数据本身 - 这就是第一次获取。如果您阻止这种情况,轮询也将永远不会开始。
老实说,这是一个奇怪的要求,这样做会用数十个状态条目填充您的缓存。
我会做一些不同的事情 - 在 端点生命周期。
这是未经测试的伪代码,您需要对其进行一些调整:
然后
在您的组件中
"Polling" here means "fetch X seconds after I have data", but of course you have to get the first data itself - and that is that first fetch. If you prevent that, polling will also never start.
Tbh., this is kind of a weird requirement and doing it like this will fill your cache with dozens of state entries.
I'd do something a little differently - solve it in the endpoint lifecycle.
This is untested pseudocode and you'll need to adjust it a bit:
and then just
in your component