edmundhung / conform

A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js.
https://conform.guide
MIT License
1.8k stars 101 forks source link

useActionState TypeError #698

Closed pythonicode closed 2 months ago

pythonicode commented 2 months ago

Describe the bug and the expected behavior

Hi there, when using Conform with the latest version of Next JS and React I'm getting the following error:

Type 'SubmissionResult<string[]> | { formError: string; } | undefined' is not assignable to type 'SubmissionResult<string[]> | null | undefined'.
  Type '{ formError: string; }' has no properties in common with type 'SubmissionResult<string[]>'.ts(2322)
form.d.ts(122, 2): The expected type comes from property 'lastResult' which is declared here on type '{ defaultValue?: { [x: string]: any; } | null | undefined; constraint?: Record<string, Constraint> | undefined; lastResult?: SubmissionResult<string[]> | null | undefined; ... 6 more ...; defaultNoValidate?: boolean | undefined; }'

Here are the relevant package versions:

"@conform-to/react": "^1.1.5",
    "@conform-to/zod": "^1.1.5",
    "@hookform/resolvers": "^3.6.0",
    "next": "14.2.4",
    "react": "18.3.1",
    "react-dom": "18.3.1",

Conform version

1.1.5

Steps to Reproduce the Bug or Issue

Here is the affected component in Next JS:

'use client';

import { useForm } from '@conform-to/react';
import { parseWithZod } from '@conform-to/zod';
import { signin } from './actions';
import { schema } from './schema';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { useActionState } from 'react';

export function SignInForm() {
    const [lastResult, action] = useActionState(signin, undefined);
    const [form, fields] = useForm({
        // Sync the result of last submission
        lastResult,

        // Reuse the validation logic on the client
        onValidate({ formData }) {
            return parseWithZod(formData, { schema });
        },
    });

    return (
        <form id={form.id} onSubmit={form.onSubmit} action={action} noValidate className='w-80'>
            <div className='mb-4'>
                <Input
                    type="email"
                    key={fields.email.key}
                    name={fields.email.name}
                    placeholder='grove@example.com'
                />
                <div className='text-xs text-red-500 my-2'>{fields.email.errors}</div>
                <Input
                    type="password"
                    key={fields.password.key}
                    name={fields.password.name}
                    placeholder='••••••••••••••••••••'
                />
                <div className='text-xs text-red-500 my-2'>{fields.password.errors} </div>
            </div>
            <Button type="submit" variant="secondary" className='w-full'>Continue</Button>
        </form>
    );
}

Simply create a file with useActionState and useForm from Conform to reproduce.

What browsers are you seeing the problem on?

Chrome

Screenshots or Videos

No response

Additional context

Here is the relevant example from the docs: https://conform.guide/integration/nextjs

Following this guide can reproduce the bug replacing the deprecated useFormState with useActionState

pythonicode commented 2 months ago

Actually I realized this was my own misunderstanding of the useActionState hook