#Using useSWR optimistic UI with prisma

1 messages · Page 1 of 1 (latest)

worn phoenix
#

The problem with useSWR optimistic UI is that await prisma.someThing.create() returns the object that was created.
and we get type error:
Argument of type '{ id: string; imie: string; wiek: number; }' is not assignable to parameter of type '{ id: string; imie: string; wiek: number; }[] | Promise<{ id: string; imie: string; wiek: number; }[] | undefined> | MutatorCallback<{ id: string; imie: string; wiek: number; }[]> | undefined'.ts(2345)

export async function createGirl({ name, age }: { name: string; age: number }) {
await new Promise((res) => setTimeout(res, 1000));
return await prisma.dziewczyna.create({
data: {
imie: name,
wiek: age,
},
});
}

  <Button
    onClick={() => {
      mutate(await createGirl({ age: 12, name: "julia" }), {
        optimisticData: [...girls, { wiek: 12, imie: "julia", id: "000" }],
      });
    }}
  >
pearl quartzBOT
#

Hi @worn phoenix. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

The type error you’re encountering is because the value you pass to SWR’s mutate function must match the expected data shape—typically an array if your SWR key is for a list. In your case, prisma.dziewczyna.create() returns a single object, but mutate expects an array (or a function returning an array), not a single object.

To fix this, you should update the local cache with the new array, including the newly created object. Here’s how you can do it:

<Button
  onClick={async () => {
    const newGirl = await createGirl({ age: 12, name: "julia" });
    mutate([...girls, newGirl], {
      optimisticData: [...girls, { wiek: 12, imie: "julia", id: "000" }],
    });
  }}
>
  Add Girl
</Button>
  • The key point is to pass an array (e.g., [...girls, newGirl]) to mutate, not just the single object returned by createGirl.
  • The optimisticData should also be an array, representing the expected state before the server confirms the mutation.

This approach is consistent with how SWR expects you to handle optimistic updates for list data, as described in the official documentation and examples for client-side data fetching and SWR usage in Next.js (Client-side Fetching, SPAs with SWR).

If you want to use the mutate function with a promise, you can also use the callback form:

mutate(async (currentGirls) => [...currentGirls, await createGirl({ age: 12, name: "julia" })], {
  optimisticData: [...girls, { wiek: 12, imie: "julia", id: "000" }],
});

This ensures the cache is always an array, matching the expected type.

#

Summary:
Always update the SWR cache with the correct data shape (an array for lists), not a single object, to avoid type errors and ensure your optimistic UI works as intended.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@worn phoenix Kapa.ai is still learning and improving, please let me know how I did by reacting below.