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