Description
When using useLazyQuery, if the trigger is called with args that contain explicit undefined values (e.g. { triggeredAddress: undefined, page: 1 }), the hook's isFetching stays false and data never updates — even though the network request fires and the returned promise resolves with correct data.
Removing the undefined key entirely (e.g. { page: 1 }) fixes the issue.
Steps to reproduce
- Call trigger with args A:
{ filterId: '1' } → works correctly, isFetching goes true, data updates
- Call trigger with args B:
{ triggeredAddress: undefined } → BUG: isFetching stays false, data stays stale
- The promise returned by the trigger resolves with the correct data
- Calling trigger with
{} instead of { triggeredAddress: undefined } works correctly
CodeSandbox reproduction
https://codesandbox.io/p/sandbox/6n7sjl
Click "Load Filtered" → wait → click "Back to Full List". The action log shows isFetching=false and stale data, while the promise resolves with the correct response.
Expected behavior
isFetching should be true while the request is in flight, and data should update when the response arrives — regardless of whether the args object contains keys with undefined values.
Actual behavior
isFetching stays false
data stays stale (shows previous trigger's result)
- The network request fires successfully
- The trigger promise resolves with correct data
lastArg updates correctly to the new args
Root cause analysis
JSON.stringify strips undefined values, so { triggeredAddress: undefined, page: 1 } and { page: 1 } produce the same cache key. However, RTK Query's internal useStableQueryArgs / copyWithStructuralSharing compares args structurally (including object keys), not by serialized cache key. The presence of an extra key with undefined value causes the hook's selector/subscription to not properly track the new cache entry's pending state.
Versions
@reduxjs/toolkit: 2.11.2
react: 19.2.3
react-redux: 9.2.0
Description
When using
useLazyQuery, if the trigger is called with args that contain explicitundefinedvalues (e.g.{ triggeredAddress: undefined, page: 1 }), the hook'sisFetchingstaysfalseanddatanever updates — even though the network request fires and the returned promise resolves with correct data.Removing the
undefinedkey entirely (e.g.{ page: 1 }) fixes the issue.Steps to reproduce
{ filterId: '1' }→ works correctly,isFetchinggoestrue, data updates{ triggeredAddress: undefined }→ BUG:isFetchingstaysfalse,datastays stale{}instead of{ triggeredAddress: undefined }works correctlyCodeSandbox reproduction
https://codesandbox.io/p/sandbox/6n7sjl
Click "Load Filtered" → wait → click "Back to Full List". The action log shows
isFetching=falseand stale data, while the promise resolves with the correct response.Expected behavior
isFetchingshould betruewhile the request is in flight, anddatashould update when the response arrives — regardless of whether the args object contains keys withundefinedvalues.Actual behavior
isFetchingstaysfalsedatastays stale (shows previous trigger's result)lastArgupdates correctly to the new argsRoot cause analysis
JSON.stringifystripsundefinedvalues, so{ triggeredAddress: undefined, page: 1 }and{ page: 1 }produce the same cache key. However, RTK Query's internaluseStableQueryArgs/copyWithStructuralSharingcompares args structurally (including object keys), not by serialized cache key. The presence of an extra key withundefinedvalue causes the hook's selector/subscription to not properly track the new cache entry's pending state.Versions
@reduxjs/toolkit: 2.11.2react: 19.2.3react-redux: 9.2.0