documentation: Smart form component form documentation not working

The smart form component from the documentation is not working: https://codesandbox.io/s/react-hook-form-smart-form-component-eqb3n

In the Form it does not like ...methods. It yields object is not a function.

Also; how do you write the Form component in typescript? It does not accept props on child object.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (9 by maintainers)

Most upvoted comments

import React, { createElement, ReactElement } from "react";
import { DeepPartial, OnSubmit, useForm } from "react-hook-form";

interface IFormProps<T> {
  defaultValues?: DeepPartial<T>;
  onSubmit: OnSubmit<T>;
}

export function Form<T>({
  defaultValues,
  children,
  onSubmit
}: IFormProps<T> & { children: ReactElement | ReactElement[] }) {
  const { register, handleSubmit } = useForm<T>({ defaultValues });

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {Array.isArray(children)
        ? children.map(child => {
            return child.props.name
              ? createElement(child.type, {
                  ...{
                    ...child.props,
                    register,
                    key: child.props.name
                  }
                })
              : child;
          })
        : children}
    </form>
  );
}

I was able to make use of the smart form in TypeScript using this, the usage is as follows: Input (I’m using a UI Component library for this)

import { Input as ChakraInput, InputProps } from "@chakra-ui/core";
import React from "react";
import { FormContextValues } from "react-hook-form";

interface IInputProps {
  register: FormContextValues["register"];
  name: string;
}

export const Input = ({
  register,
  name,
  ...props
}: Partial<IInputProps & InputProps<HTMLInputElement>>) => (
  <ChakraInput name={name} ref={register} {...props} />
);

Form setup (passing in the generic gives Type safety for defaultValues)

interface UserGuildInput {
  prefix: string
}

<Form<UserGuildInput>
  defaultValues={{ prefix: data.guild.prefix }}
  onSubmit={onSubmit}
>
  <Input name="prefix" />
  <Input name="language" />

  <button type="submit">submit</button>
</Form>

I’m not too experienced with TypeScript so input is welcome 😃

Yeh I figured. It would also be pretty cool to embed validation rules into the setup. I guess it could go into either the Form as props or the individual UI components.

And thanks a bunch for a great library (and extremely quick response)