Oops! The tRPC and Mantine CSS Custom hook call is invalid. It seems there was an error

I encountered an Unhandled Runtime Error while working with Next.js. Previously, I had no issues calling an arrow function with a void type until I integrated the useForm hook from the Mantine CSS library.

Unhandled Runtime Error
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This error may occur due to:
1. Mismatching versions of React and the renderer (such as React DOM)
2. Violating the Rules of Hooks
3. Multiple copies of React in the same application
Refer to https://reactjs.org/link/invalid-hook-call for troubleshooting tips.

Below is the code snippet.

import {
  Container,
  Input,
  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 }
  )

  const createTask = (values: { title: string }) => {
    return api.task.create
      .useMutation({ onSuccess: async () => await refetchTasks() })
      .mutate({
        title: values.title,
        recursion: {},
        analytics: {},
        reminder: {},
        taskSequence: {},
      })
  }

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

  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

The version provided above allowed me to successfully add data to my database.

import {
  Container,
  Input,
  Box,
  Text,
  Button,
  Flex,
  ActionIcon,
  ScrollArea,
} from '@mantine/core'
import { useSession } from 'next-auth/react'
import { api } from '~/utils/api'
import { HiTrash } from 'react-icons/hi'
import type { BaseSyntheticEvent } from 'react'

const TodoApp = () => {
  const { data: sessionData } = useSession()

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

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

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

  return (
    <>
      <Container my={64} px={32} bg='gray.8' h='80vh' w='40rem'>
        <Input
          py={64}
          placeholder='Add Your Task Here.'
          onKeyDown={e => {
            if (e.currentTarget.value.length < 1) return
            if (e.key === 'Enter') {
              createTask.mutate({
                title: e.currentTarget.value,
                recursion: {},
                analytics: {},
                reminder: {},
                taskSequence: {},
              })
              e.currentTarget.value = ''
            }
          }}
        />
        <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.125rem'
                    onClick={() => {
                      deleteTask.mutate({ id: task.id })
                    }}
                  />
                </ActionIcon>
              </Flex>
            ))}
          </Flex>
        </ScrollArea>
      </Container>
    </>
  )
}

export default TodoApp

Answer №1

Splitting up the call methods for .useMutation and .mutate made a noticeable difference in performance. The reason behind this improvement is still unclear to me.

...
  const addNewTask = api.task.add.useMutation({
    onSuccess: async () => await fetchUpdatedTasks(),
  })

  const submitTaskValues = (values: { title: string }) =>
    addNewTask.mutate({
      title: values.title,
      recursion: {},
      analytics: {},
      reminder: {},
      taskSequence: {},
    })

  const removeTask = api.task.remove.useMutation({
    onSuccess: async () => await fetchUpdatedTasks(),
  })

  return (
    <>
      <Container my={64} px={32} bg='gray.8' h='80vh' w='40rem'>
        <form
          onSubmit={form.onSubmit(values => {
            if (form.values.title.length <= 0) return
            console.log(values)
            submitTaskValues(values)
            form.values.title = ''
          })}
        >
          <TextInput
            py={64}
            placeholder='Enter Your New Task Here.'
            {...form.getInputProps('title')}
          />
        </form>
...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can RxJS be used to handle only the first value returned when calling multiple URLs?

I am faced with the challenge of having multiple URLs containing crucial information. My goal is to find a specific ID within these URLs, but I do not know which URL holds the necessary details. The approach I'm taking involves calling each URL and us ...

Modify the interface type whilst maintaining the structure of nested objects

In my system, I have a specific interface that outlines the structure of a NoSQL document schema. This includes strings, arrays, nested objects, and more. Here's an example representation: interface IStudentSchema { name: string; age: string; f ...

Angular 7/8 - A guide to accessing URL parameters within the app component

Currently, I have implemented Single Sign-On feature on my application. However, for testing purposes, I need to extract values from the URL localhost:4200/?id=test&name=testing&<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfe ...

Array has been updated, but the view is not reflecting the changes

At first, the user collection is represented by Model:1 { "_id":"sodjflkadkjj2342", "role:["customer"], "active":true, "email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="15767d677c66557477763b767a78"> ...

Checking for the existence of a custom VPC within AWS CDK: A comprehensive guide

While working on a CDK script, I encountered a situation where I needed to utilize the default VPC. Here is the code snippet for that: vpc = ec2.Vpc.fromLookup(this, "UseDefaultVPC", { isDefault: true }); In case I need to use an existing non- ...

How can I call an external function in Typescript within an Angular 2 project using C3 js with the c3

I've been struggling with a specific issue for quite some time now, but I can't seem to pinpoint the exact problem. I'm not sure if it's related to Angular or C3. Oddly enough, I'm unable to execute my method within the c3.generat ...

Personalized context hook TypeScript

I have been experimenting with a custom hook and the context API, based on an interesting approach that I found in this repository. However, I encountered an error when trying to use it with a simple state for a number. Even though I wanted to create a mo ...

Reviewing for the presence of "Undefined" in the conditional statement within Transpiled Javascript code for

While perusing through some transpiled Angular code, I came across this snippet: var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) { I'm puzzled by the usage of undefined in this context. Can an ...

leveraging the import statement in conjunction with SystemJs

Currently, I am in the process of creating a sample code using TypeScript and SystemJS for the browser. In my app.ts file: import {Person,add as test} from './testLib' In the generated app.js file (by TypeScript compiler): var testLib_1 = re ...

Angular 6 component experiencing issues with animation functionality

I've implemented a Notification feature using a Notification component that displays notifications at the top of the screen. The goal is to make these notifications fade in and out smoothly. In my NotificationService, there's an array that holds ...

`MongoDb aggregation performance degradation with numerous collections (join)`

I am currently working on a project using the MEAN stack and I have noticed that I am utilizing a significant number of collections in my aggregation, resulting in a heavy reliance on lookup. This has had a negative impact on performance, causing the execu ...

gather data from a separate HTML document's form

Within an html file, users fill out a form and database queries are executed to display Google Maps locations. My objective is to store this data in a variable so that it can be used in another html file. This second html file will utilize the previous va ...

Tips for minimizing the influence of external code in Next.js

What steps can I take to minimize the impact of third-party code on my next.js app? I have incorporated Google Analytics and Google AdSense on my website, but it is causing performance issues. view this illustration _document.js import Document, { Html, ...

Using the Mongoose library in the API directory of a Next.js 13.2 application results in a syntax error

Inside hello.js import connectMongo from '../../../util/connectDB'; import UserModel from '../../../models/UserModel'; import { NextResponse } from 'next/server' export async function GET(request) { return NextResponse.json ...

Can you surpass the type declarations of a module at the local level?

Is there a way to change the appearance of a specific typescript module for those importing it? I have webpack rules that modify the exports of this module during transpile time, which is why I want to override its appearance. In my custom.d.ts file, I h ...

The value returned by router.query in Next.js is undefined

I am dynamically passing the artistName and trying to retrieve it in another component located at app/artist/[artistId]/page.js. However, I am unable to destructure artistName even though it is being passed correctly. CollectionItem.js import Image from & ...

Tips on modifying the main color of an application through the UI in React JS (Next JS) with the help of tailwind CSS

If the primary color of each button is initially set to bg-gray-600, and you want to change it to bg-indigo-600</ode>, attempting to use template literals seems ineffective in altering the UI.</p> <pre><code>const customizeButton = ...

Double Execution of Next.js Function

Whenever I click, my addToCart function is running twice. //Function const addToCart = useCallback(() => { if (produto && cartItems) { setCartItems((prev: LocalStorageItem[]) => { if (!Array.isArray(prev)) { retur ...

Utilizing AngularJS and PHP to power an email submission form

I'm encountering an issue where the email I'm sending with AngularJS and PHP has empty parameters like name, email, etc. Despite my efforts to validate input using AngularJS, the data doesn't seem to be reaching my email account correctly. ...

Transferring the selected option from a drop-down menu to a PHP page using an HTML form

I'm currently working on developing an HTML form that will send the user's question and the selected topic to a PHP page. The topics are retrieved from a MySQL database using PHP. My goal is to submit the chosen topic value from a dropdown menu, ...