Upon clicking the SubmitBtn in the LoginForm component for the first time, the form fails to submit, and nothing appears to happen. The onInvalid function returns an empty object ({}). However, on the second attempt, the onInvalid function provides the following feedback:
{
    username: { message: 'Required', type: 'invalid_type', ref: undefined },
    confirmPassword: { message: 'Required', type: 'invalid_type', ref: undefined }
}
Despite this detailed validation error, the form remains unsubmitted, and no observable changes occur.
LogInForm :
import { FormControl } from '@chakra-ui/react'
import SubmitBtn from '../SubmitBtn'
import InputComponent from '../InputComponent';
import LoginService from '../../../services/loginService';
const LoginForm = () => {
    const { handleSubmit, onsubmit, register, isPending, errors, onInvalid } = LoginService()
    return (
        <form onSubmit={handleSubmit(onsubmit, onInvalid)}>
            <FormControl isRequired mb='4'>
                <InputComponent label='Email Address' register={register} errorsType={errors} errorsMessage={errors.email?.message} placeholder='[email protected]' type='email' name='email' helper='please make sure to enter a valid email address' />
            </FormControl>
            <FormControl isRequired mb='4'>
                <InputComponent label='Password' register={register} errorsType={errors} errorsMessage={errors.password?.message} placeholder='enter your password: ******' type='password' name='password' helper='please make sure to enter the correct password' />
            </FormControl>
            <SubmitBtn loading={isPending} textloading='logging in' >Login</SubmitBtn>
        </form>
    )
}
export default LoginForm
InputComponent
import { FormHelperText, Input, FormLabel } from '@chakra-ui/react'
import type { FieldErrors, UseFormRegister } from 'react-hook-form';
import { FormType } from '../../types/types';
type InputComponentPropsTypes = {
    register: UseFormRegister<FormType>,
    errorsType?: FieldErrors<FormType> | undefined,
    errorsMessage: string | undefined,
    type: React.HTMLInputTypeAttribute,
    name: keyof FormType
    label: string
    placeholder: string,
    helper: string
}
const InputComponent = ({ label, errorsType, errorsMessage, register, name, type, placeholder, helper }: InputComponentPropsTypes) => {
    return (
        <>
            <FormLabel>{label}</FormLabel>
            <Input {...register(name)} type={type} placeholder={placeholder} focusBorderColor='teal.500' />
            {errorsType && errorsType[name] ?
                <FormHelperText color='red'>{errorsMessage}</FormHelperText>
                :
                <FormHelperText>{helper}</FormHelperText>
            }
        </>
    )
}
export default InputComponent
LoginService
import { useToast } from '@chakra-ui/react'
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form'
import axios from 'axios'
import { useMutation } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import { z } from 'zod'
import { useStore } from '../utils/store';
import { FormSchema, FormType } from '../types/types';
import { API_URL } from '../constants';
const LoginService = () => {
    const setToken = useStore(store => store.setToken)
    const toast = useToast()
    const navigation = useNavigate()
    const { reset, register, handleSubmit, formState: { errors } } = useForm<FormType>({ resolver: zodResolver(FormSchema) })
    const { mutateAsync: loginUser, isPending } = useMutation({
        mutationKey: ['loginUser'],
        mutationFn: async (user: FormType) => {
            await axios.post(`${API_URL}auth/login`, user).then(res => {
                setToken(res.data.token)
                localStorage.setItem('token', res.data.token)
            })
            reset()
        }
    })
    const onInvalid = () => console.log(errors)
    const onsubmit = (user: FormType) => {
        console.log('clicked')
        loginUser(user, {
            onSuccess: () => {
                toast({
                    title: 'successfully logged in',
                    position: 'top',
                    status: 'success',
                    isClosable: true,
                })
                navigation('/home')
            },
            onError: (error) => {
                if (error instanceof z.ZodError) {
                    toast({
                        title: `${error.issues[0].message}`,
                        position: 'top',
                        status: 'error',
                        isClosable: true,
                    })
                } else toast({
                    title: 'something went wrong',
                    position: 'top',
                    status: 'error',
                    isClosable: true,
                })
            }
        })
    }
    return {
        onsubmit,
        onInvalid,
        register,
        handleSubmit,
        isPending,
        errors
    }
}
export default LoginService
Types
import { z } from "zod"
export type AuthType = 'register' | 'login'
export const FormSchema = z.object({
    username: z.string().nullable(),
    email: z.string().email(),
    password: z.string().min(8, { message: 'Must be 8 or more characters long' }),
    confirmPassword: z.string().nullable()
}).refine(data => data.password === data.confirmPassword, {
    message: 'confirmed password must match the password',
    path: ['confirmPassword']
})
export type FormType = z.infer<typeof FormSchema>;
The form was functioning correctly initially. However, after splitting it into multiple components, the issue arose.
                        
The solution I found is to add a new schema for the login.
And picking only the email and password from FormType in loginService.
It should work with the optional() method, but I don't know why it didn't work.