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:
const [storedToken, setStoredToken] = useState<string>(getStoredToken());
const [tokenDebounced] = useDebounce(storedToken, 9000);
const { data } = useRefreshUserQuery(tokenDebounced);
useEffect(() => {
if (data) {
setStoredToken(data);
// console.log(newToken);
}
}, [data]);
The useEffect content and data 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
const [storedToken, setStoredToken] = useState<string>(getStoredToken());
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 new baseQuery, based on fetchBaseQuery that will set header and\or to include cookies with credentials: "include" with a token from localStorage 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:
const { data, error, refetch } = useRefreshUserQuery(undefined ,{
pollingInterval: 9000,
});