DINO
DINO6mo ago

useMutation() runs 3 times

Hello, I have this weird problem that all my mutations across the app runs 3 times I don't know why. This is my API in the backend:
import { initTRPC } from '@trpc/server'
import superjson from 'superjson'

import routers from './routers'
import { brandFormSchema } from './zod-schemas'

const t = initTRPC.create({ isServer: true, transformer: superjson })

export const router = t.router({
...routers
})

export type AppRouter = typeof router
import { initTRPC } from '@trpc/server'
import superjson from 'superjson'

import routers from './routers'
import { brandFormSchema } from './zod-schemas'

const t = initTRPC.create({ isServer: true, transformer: superjson })

export const router = t.router({
...routers
})

export type AppRouter = typeof router
And this is how I use them in the client:
import { notifications } from '@mantine/notifications'
import { trpcReact } from '@renderer/util/trpc'

import BrandForm from './brand-form'

type Props = {
onCreated: () => void
onCancel: () => void
}

function CreateBrand({ onCreated, onCancel }: Props): JSX.Element {
const utils = trpcReact.useUtils()

const { mutate, isLoading } = trpcReact.brand.create.useMutation({
onSuccess: (): void => {
utils.brand.all.invalidate()
notifications.show({
message: 'Added brand successfully!',
color: 'green'
})
},
onError: (error): void => {
notifications.show({
message: 'Brand not added!' + error,
color: 'red'
})
}
})

return (
<BrandForm
loading={isLoading}
submitHandler={(values): void => {
mutate(values)
onCreated()
}}
cancelHandler={(): void => {
onCancel()
}}
/>
)
}

export default CreateBrand
import { notifications } from '@mantine/notifications'
import { trpcReact } from '@renderer/util/trpc'

import BrandForm from './brand-form'

type Props = {
onCreated: () => void
onCancel: () => void
}

function CreateBrand({ onCreated, onCancel }: Props): JSX.Element {
const utils = trpcReact.useUtils()

const { mutate, isLoading } = trpcReact.brand.create.useMutation({
onSuccess: (): void => {
utils.brand.all.invalidate()
notifications.show({
message: 'Added brand successfully!',
color: 'green'
})
},
onError: (error): void => {
notifications.show({
message: 'Brand not added!' + error,
color: 'red'
})
}
})

return (
<BrandForm
loading={isLoading}
submitHandler={(values): void => {
mutate(values)
onCreated()
}}
cancelHandler={(): void => {
onCancel()
}}
/>
)
}

export default CreateBrand
I am sure that the call from the client doesn't run 3 times. I checked it with console.log. I would be grateful if anyone helped. THanks.
7 Replies
DINO
DINO6mo ago
Also it's not a problem of the the way I create new row because I tried to console.log() at the start of the mutation function and it turned out it runs 3 times.
const create = t.procedure.input(brandFormSchema).mutation(async (req) => {
try {
console.log('=== running create brand mutation')
const { input: brandFormValues } = req
const em = orm.em.fork()
await em.persistAndFlush(em.create(Brand, brandFormValues))
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
createErrorLog(err.message, 'Create brand.')
throw err
}
})
const create = t.procedure.input(brandFormSchema).mutation(async (req) => {
try {
console.log('=== running create brand mutation')
const { input: brandFormValues } = req
const em = orm.em.fork()
await em.persistAndFlush(em.create(Brand, brandFormValues))
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
createErrorLog(err.message, 'Create brand.')
throw err
}
})
Nick
Nick6mo ago
Does it succeed 3 times or fail? RQ has retries
DINO
DINO6mo ago
It succeeds 3 times
Nick
Nick6mo ago
Have you tried logging the even handler on the UI? Does that trigger multiple times? That’s what you logged before I assume? Do 3 network calls go out? It’s important to figure out where the number 3 begins But it’s a strange one of the network call is coming back with a 2xx status
DINO
DINO6mo ago
I think I found where the problem at. I am using Electron with electron-trpc and I guess it's from create createIPCHandler handler multiple times.
Nick
Nick6mo ago
Ah that’s a niche case
DINO
DINO6mo ago
I have solved it. It was calling createIPCHandler multiple times. Thank you very much for your time.