import { describe, bench } from "vitest"; import { Field, Form } from "houseform"; import { z } from "zod"; import { cleanup, fireEvent, getByTestId, render, } from "@testing-library/react"; import { Formik, Field as FormikField } from "formik"; import { toFormikValidationSchema } from "zod-formik-adapter"; import { FieldProps } from "formik/dist/Field"; import { Controller, useForm } from "react-hook-form"; import React, { useState } from "react"; import { zodResolver } from "@hookform/resolvers/zod"; import { ErrorMessage } from "@hookform/error-message"; const arr = Array.from({ length: 1000 }, (_, i) => i); function HouseFormOnSubmitBenchmark() { return (
{({ submit }) => ( <> {arr.map((num, i) => { return ( {({ value, setValue, onBlur, errors }) => { return (
setValue(e.target.valueAsNumber)} placeholder={`Number ${i}`} /> {errors.map((error) => (

{error}

))}
); }}
); })} )}
); } function FormikOnSubmitBenchmark() { return ( {}} > {({ submitForm }) => ( <> {arr.map((num, i) => ( {(props: FieldProps) => (
{props.meta.error}
)}
))} )}
); } function ReactHookFormOnSubmitBenchmark() { const { register, handleSubmit, formState: { errors }, } = useForm({ defaultValues: { num: arr, }, mode: "onSubmit", resolver: zodResolver( z.object({ num: z.array(z.number().min(3, "Must be at least three")), }) ), }); return ( <> {arr.map((num, i) => { return (
); })} ); } function ReactHookFormHeadlessOnSubmitBenchmark() { const { control, handleSubmit } = useForm({ defaultValues: { num: arr, }, mode: "onSubmit", resolver: zodResolver( z.object({ num: z.array(z.number().min(3, "Must be at least three")), }) ), }); return ( <> {arr.map((num, i) => { return ( { return (
onChange(event.target.valueAsNumber)} placeholder={`Number ${i}`} /> {error &&

{error.message}

}
); }} name={`num.${i}`} /> ); })} ); } describe("Validates onSubmit on 1,000 form items", () => { bench( "HouseForm", async () => { const { getByText, findAllByText, queryAllByText } = render( ); if (queryAllByText("Must be at least three")?.length) { throw "Should not be present yet"; } fireEvent.click(getByText("Submit")); await findAllByText("Must be at least three"); }, { setup(task) { task.opts.beforeEach = () => { cleanup(); }; }, } ); bench( "Formik", async () => { const { getByText, findAllByText, queryAllByText } = render( ); if (queryAllByText("Must be at least three")?.length) { throw "Should not be present yet"; } fireEvent.click(getByText("Submit")); await findAllByText("Must be at least three"); }, { setup(task) { task.opts.beforeEach = () => { cleanup(); }; }, } ); bench( "React Hook Form", async () => { const { getByText, findAllByText, queryAllByText } = render( ); if (queryAllByText("Must be at least three")?.length) { throw "Should not be present yet"; } fireEvent.click(getByText("Submit")); await findAllByText("Must be at least three"); }, { setup(task) { task.opts.beforeEach = () => { cleanup(); }; }, } ); bench( "React Hook Form (Headless)", async () => { const { getByText, findAllByText, queryAllByText } = render( ); if (queryAllByText("Must be at least three")?.length) { throw "Should not be present yet"; } fireEvent.click(getByText("Submit")); await findAllByText("Must be at least three"); }, { setup(task) { task.opts.beforeEach = () => { cleanup(); }; }, } ); });