react-admin icon indicating copy to clipboard operation
react-admin copied to clipboard

When using `meta` in Edit, it breaks cache update in `useUpdate`

Open mikhail-fedosenko opened this issue 1 year ago • 2 comments

What you were expecting: When I pass queryOptions and mutationOptions with meta in Edit component, then update the record with some new values, the cache in React-Query is updated with queryKey that includes meta.

What happened instead: React-Query cache item is updated with queryKey that misses meta.

Steps to reproduce:

  1. Go to Posts screen.
  2. Click on any post to edit it.
  3. Change Title to new value.
  4. Press Save - you are returned to List view - OK.
  5. Title of the updated Post in List view is updated - OK.
  6. Click on the same post to edit it.

Expected result: Title text input has new value in Edit screen (because the React-Query cache should have been updated with new record).

Actual result: Title text input has old value for 3 seconds in Edit screen, then it gets updated to new value (3s is a delay in a dataProvider).

Related code: https://stackblitz.com/edit/github-aky8mx-pebq3a?file=src%2Fposts%2FPostEdit.tsx

  const meta = { param: 123 }
  
  return (
    <Edit
      title={<PostTitle />}
      actions={<EditActions />}
      mutationOptions={{ meta }}
      queryOptions={{ meta }}
    >

I've set a timeout of 3 seconds in delayedDataProvider.

Root cause updateCache in useUpdate.ts uses meta from options, that were destructured in useEditController. The meta value was dropped. useEditController.ts:

    const {
        onSuccess,
        onError,
        meta: mutationMeta,
        ...otherMutationOptions
    } = mutationOptions;

    // ...

    const [update, { isLoading: saving }] = useUpdate<
        RecordType,
        MutationOptionsError
    >(resource, recordCached, {
        ...otherMutationOptions,
        mutationMode,
        returnPromise: mutationMode === 'pessimistic',
    });

useUpdate.ts

    const { id, data, meta } = params;
    // ...

    const updateCache = ({ resource, id, data }) => {
        // ...
        queryClient.setQueryData(
            [resource, 'getOne', { id: String(id), meta }],
            (record: RecordType) => ({ ...record, ...data }),
            { updatedAt }
        // ...
    }

    // ...

Environment

  • React-admin version: 4.16.3
  • React version: 17.0.2

mikhail-fedosenko avatar Dec 22 '23 13:12 mikhail-fedosenko

Thanks for the repro and the detailed explanation.

But I wonder if it is a bug we can fix. If we use the meta in the cache key, then the item in the list view won't be updated anymore, unless the list uses the same meta.

But that's probably less a problem than the current bug.

Since you've tracked down the root cause, would you mind opening a PR to fix it?

fzaninotto avatar Dec 22 '23 15:12 fzaninotto

I'll try to make a PR a bit later, cause it's not a priority for me (and not a blocker..).

mikhail-fedosenko avatar Dec 28 '23 14:12 mikhail-fedosenko