Passing register as a dynamic parameters inside a .map() function (React-hook-form)

Viewed 23

I'm using an object to create the parameters for my form, so I can loop through the data and automatically create the form rather than adding everything manually. My problem comes when trying to pass a variable to the register, everything stops working.

Here's what the object looks like:

const form = [
  {
    name: "styles",
    type: "graphic",
    checkboxes: [
      {
        value: "dresses",
        label: "Dresses"
      }
    ]
  }
];

export default form;

Checkbox.tsx:

const Checkbox = React.forwardRef(
  (
    {
      label,
      name,
      value,
      onChange,
      defaultChecked,
      errors,
      onBlur,
      errorMessage,
      ...rest
    }: any,
    forwardedRef: any
  ) => {
    return (
      <div className="grow w-full">
        <label htmlFor={name}>{label}</label>
        <input
          type="checkbox"
          value={value}
          name={name}
          onChange={onChange}
          onBlur={onBlur}
          ref={forwardedRef}
          {...rest}
        />
        {errors && <p className="error">{errors.message && errorMessage}</p>}
      </div>
    );
  }
);

And here's how I use it in the parent component:

const schema = yup.object().shape({
  name: yup.array().min(1)
});

export default function App() {
  const {
    handleSubmit,
    register,
    formState: { errors }
  } = useForm({
    resolver: yupResolver(schema)
  });

  const onSubmit = (data: any) => {
    console.log("clicked");
    console.log(errors, "errors");
    alert(JSON.stringify(data));
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {form?.map((section: any, index: any) => {
        console.log(section, "s");
        const name = section.name;
        return (
          <div key={index}>
            <h2 className="font-bold">{name}</h2>
            {section.checkboxes.map((checkbox: any, index: any) => {
              return (
                <>
                  <Checkbox
                    key={index}
                    {...register(name)}
                    name={name}
                    value={checkbox.value}
                    label={checkbox.label}
                  />
                </>
              );
            })}
            {errors.name && (
              <p className="error">
                {errors.name.message && `Please select one item`}
              </p>
            )}
          </div>
        );
      })}
      <button type="submit">Submit</button>
    </form>
  );
}

As you can see from this Codesandbox, everything works if you wrap the name variable in quotes so it's a string, but not as a variable.

Things I've tried:

                {...register(`${name}`)}
                name={name}

                {...register(name.toString())}
                name={name}

This works:

                {...register("name")}
                name={name}

But then I lose the ability to use name as variable in my real code (if that makes sense),

As you can probably tell I'm a bit lost here. There's several different posts on Stackoverflow referring to this issue but none of the answers make any sense to me.

Any ideas what I'm doing wrong?

0 Answers
Related