You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js集成Mantine useForm与tRPC时触发无效Hook调用错误

解决Next.js中引入Mantine useForm后的Invalid Hook Call错误

错误根源

你在createTask函数内部调用了api.task.create.useMutation这个Hook,违反了React的Hook核心规则:Hook只能在函数组件的顶层或自定义Hook的顶层调用,不能嵌套在普通函数、事件回调或者循环/条件判断里。当表单提交触发createTask时,相当于在非组件顶层执行了Hook,直接抛出Invalid hook call错误。

修复步骤

把useMutation的定义移到组件顶层,和其他Hook(useForm、useSession、useQuery等)放在一起,然后在createTask里直接调用已定义好的mutation的mutate方法即可。

修改后的完整代码

import {
  Container,
  Text,
  Flex,
  ActionIcon,
  ScrollArea,
  TextInput,
} from '@mantine/core'
import { useForm } from '@mantine/form'
import { useSession } from 'next-auth/react'
import { api } from '~/utils/api'
import { HiTrash } from 'react-icons/hi'

const TodoApp = () => {
  const form = useForm({
    initialValues: {
      title: '',
    },
  })

  const { data: sessionData } = useSession()

  const { data: tasks, refetch: refetchTasks } = api.task.getAll.useQuery(
    undefined,
    { enabled: sessionData?.user !== undefined }
  )

  // 将useMutation移至组件顶层,符合Hook调用规则
  const createTaskMutation = api.task.create.useMutation({
    onSuccess: async () => await refetchTasks()
  })

  const deleteTask = api.task.delete.useMutation({
    onSuccess: async () => await refetchTasks(),
  })

  // 普通函数内仅调用mutate方法,不再触发Hook调用
  const createTask = (values: { title: string }) => {
    createTaskMutation.mutate({
      title: values.title,
      recursion: {},
      analytics: {},
      reminder: {},
      taskSequence: {},
    })
  }

  return (
    <>
      <Container my={64} px={32} bg='gray.8' h='80vh' w='40rem'>
        <form
          onSubmit={form.onSubmit(values => {
            console.log(values)
            createTask(values)
          })}
        >
          <TextInput
            py={64}
            placeholder='Add Your Task Here.'
            {...form.getInputProps('title')}
          />
        </form>
        <ScrollArea h={400}>
          <Flex gap='md' justify='flex-start' direction='column'>
            {tasks?.map(task => (
              <Flex
                key={task.id}
                justify='space-between'
                bg='pink.9'
                p={8}
                sx={{ borderRadius: '0.4rem' }}
              >
                <Text fw={700} c='white'>
                  {task.title}
                </Text>
                <ActionIcon color='grape' variant='transparent'>
                  <HiTrash
                    size='1.5rem'
                    onClick={() => {
                      deleteTask.mutate({ id: task.id })
                    }}
                  />
                </ActionIcon>
              </Flex>
            ))}
          </Flex>
        </ScrollArea>
      </Container>
    </>
  )
}

export default TodoApp

额外排查方向(若修复后仍报错)

  • 核对React、React DOM与Mantine相关依赖的版本兼容性,确保版本匹配
  • 执行npm ls react查看依赖树,排查项目中是否存在多个React副本

内容的提问来源于stack exchange,提问作者circular_reference

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 05:30:13