@@ -59,6 +59,10 @@ export const useMutationWithMutationMode = <
5959 useEffect ( ( ) => {
6060 paramsRef . current = params ;
6161 } , [ params ] ) ;
62+ // This ref won't be updated when params change in an effect, only when the mutate callback is called (See L247)
63+ // This ensures that for undoable and optimistic mutations, the params are not changed by side effects (unselectAll for instance)
64+ // _after_ the mutate function has been called, while keeping the ability to change declaration time params _until_ the mutation is called.
65+ const paramsAtExecutionTimeRef = useRef < Partial < TVariables > > ( params ) ;
6266
6367 // Ref that stores the snapshot of the state before the mutation to allow reverting it
6468 const snapshot = useRef < Snapshot > ( [ ] ) ;
@@ -96,7 +100,6 @@ export const useMutationWithMutationMode = <
96100 {
97101 mutationKey,
98102 mutationFn : async params => {
99- const callTimeParams = { ...paramsRef . current , ...params } ;
100103 if ( params == null ) {
101104 throw new Error (
102105 'useMutationWithMutationMode mutation requires parameters'
@@ -105,7 +108,7 @@ export const useMutationWithMutationMode = <
105108
106109 return (
107110 mutateWithMiddlewares
108- . current ( callTimeParams as TVariables )
111+ . current ( params as TVariables )
109112 // Middlewares expect the data property of the dataProvider response
110113 . then ( ( { data } ) => data )
111114 ) ;
@@ -216,7 +219,10 @@ export const useMutationWithMutationMode = <
216219 ( params : TVariables ) => {
217220 // Store the final parameters which might have been changed by middlewares
218221 paramsRef . current = params ;
219- return mutationFnEvent ( params ) ;
222+ return mutationFnEvent ( {
223+ ...params ,
224+ ...callTimeParams ,
225+ } ) ;
220226 }
221227 ) ;
222228 } else {
@@ -234,6 +240,9 @@ export const useMutationWithMutationMode = <
234240 // because they may change afterwards, which would break the undoable mode
235241 // as the previousData would be overwritten by the optimistic update
236242 paramsRef . current = params ;
243+ // Also store them in a ref that will always be used for optimistic and undoable updates
244+ // as their actual mutation happens after their side effects which may change the params (unselectAll for instance)
245+ paramsAtExecutionTimeRef . current = params ;
237246
238247 if ( mutationMode ) {
239248 mode . current = mutationMode ;
@@ -246,7 +255,7 @@ export const useMutationWithMutationMode = <
246255 }
247256
248257 snapshot . current = getSnapshotEvent (
249- { ...paramsRef . current , ...callTimeParams } ,
258+ { ...paramsAtExecutionTimeRef . current , ...callTimeParams } ,
250259 {
251260 mutationMode : mode . current ,
252261 }
@@ -255,13 +264,13 @@ export const useMutationWithMutationMode = <
255264 if ( mode . current === 'pessimistic' ) {
256265 if ( returnPromise ) {
257266 return mutation . mutateAsync (
258- { ...paramsRef . current , ...callTimeParams } ,
267+ { ...paramsAtExecutionTimeRef . current , ...callTimeParams } ,
259268 // We don't pass onError and onSettled here as we will call them in the useMutation hook side effects
260269 { onSuccess, ...otherCallTimeOptions }
261270 ) ;
262271 }
263272 return mutation . mutate (
264- { ...paramsRef . current , ...callTimeParams } ,
273+ { ...paramsAtExecutionTimeRef . current , ...callTimeParams } ,
265274 // We don't pass onError and onSettled here as we will call them in the useMutation hook side effects
266275 { onSuccess, ...otherCallTimeOptions }
267276 ) ;
@@ -276,7 +285,7 @@ export const useMutationWithMutationMode = <
276285
277286 // Optimistically update to the new value
278287 const optimisticResult = updateCacheEvent (
279- { ...paramsRef . current , ...callTimeParams } ,
288+ { ...paramsAtExecutionTimeRef . current , ...callTimeParams } ,
280289 {
281290 mutationMode : mode . current ,
282291 } ,
@@ -288,7 +297,7 @@ export const useMutationWithMutationMode = <
288297 if ( onSuccess ) {
289298 onSuccess (
290299 optimisticResult ,
291- callTimeParams ,
300+ { ... paramsAtExecutionTimeRef . current , ... callTimeParams } ,
292301 {
293302 snapshot : snapshot . current ,
294303 } ,
@@ -304,7 +313,7 @@ export const useMutationWithMutationMode = <
304313 ) {
305314 mutationOptions . onSuccess (
306315 optimisticResult ,
307- callTimeParams ,
316+ { ... paramsAtExecutionTimeRef . current , ... callTimeParams } ,
308317 {
309318 snapshot : snapshot . current ,
310319 } ,
@@ -319,24 +328,36 @@ export const useMutationWithMutationMode = <
319328
320329 if ( mode . current === 'optimistic' ) {
321330 // call the mutate method without success side effects
322- return mutation . mutate ( callTimeParams ) ;
331+ return mutation . mutate ( {
332+ ...paramsAtExecutionTimeRef . current ,
333+ ...callTimeParams ,
334+ } ) ;
323335 } else {
324336 // Undoable mutation: add the mutation to the undoable queue.
325337 // The Notification component will dequeue it when the user confirms or cancels the message.
326338 addUndoableMutation ( ( { isUndo } ) => {
327339 if ( isUndo ) {
328340 if ( onUndo ) {
329- onUndoEvent ( callTimeParams , {
330- mutationMode : mode . current ,
331- } ) ;
341+ onUndoEvent (
342+ {
343+ ...paramsAtExecutionTimeRef . current ,
344+ ...callTimeParams ,
345+ } ,
346+ {
347+ mutationMode : mode . current ,
348+ }
349+ ) ;
332350 }
333351 // rollback
334352 snapshot . current . forEach ( ( [ key , value ] ) => {
335353 queryClient . setQueryData ( key , value ) ;
336354 } ) ;
337355 } else {
338356 // call the mutate method without success side effects
339- mutation . mutate ( callTimeParams ) ;
357+ mutation . mutate ( {
358+ ...paramsAtExecutionTimeRef . current ,
359+ ...callTimeParams ,
360+ } ) ;
340361 }
341362 } ) ;
342363 }
0 commit comments