Форма подключения реакции: отправьте форму с вложенными компонентами или извлеките поля вложенных компонентов для отправки.

#javascript #reactjs #nested #react-component #react-hook-form

#javascript #reactjs #вложенный #реагирующий компонент #реагирующая форма подключения

Вопрос:

У меня есть форма с несколькими компонентами в ней (каждый из которых является либо функциональным, либо компонентом на основе класса), содержащим несколько полей ввода или переключателей. Когда я отправляю форму, я либо хочу отправить поля, вложенные в компоненты, вместе с данными формы, либо я должен иметь возможность извлекать данные полей и затем отправлять их (не уверен, какой подход будет лучшим и почему?). Как я могу этого добиться?

Код :

 import React from "react";
import { useForm } from "react-hook-form";

export default function TestComponent() {
  const { register, handleSubmit, errors } = useForm();
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="name">Name</label>
      <input type="text" id="name" name="name" ref={register({ required: true, maxLength: 30 })} />
      {errors.name amp;amp; errors.name.type === "required" amp;amp; <span>This is required</span>}
      {errors.name amp;amp; errors.name.type === "maxLength" amp;amp; <span>Max length exceeded</span> }
      <NestedComponent1 />
      <NestedComponent2 />
      <input type="submit" />
    </form>
  );
}

function NestedComponent1() {
    return (
        <div>
            <input type="text" id="nested-name" name="nestedName" />
            <input type="text" id="nested-name2" name="nestedName2" />
            <input type="text" id="nested-name3" name="nestedName3" />
        </div>
    );
}

function NestedComponent2() {
    return (
        <div>
            <input type="text" id="nested-comp2-name" name="nestedcomp2Name" />
            <input type="text" id="nested-comp2-name2" name="nestedcomp2Name2" />
            <input type="text" id="nested-comp2-name3 name="nestedcomp2Name3" />
        </div>
    );
}
 

Ответ №1:

Вы могли бы использовать перехват useFormContext , чтобы избежать передачи контекста в качестве реквизита https://react-hook-form.com/api/useformcontext

Вам нужно только обернуть свою форму FormProvider компонентом, чтобы вы могли использовать контекст useFormContext во вложенном компоненте

 export default function TestComponent() {
    const methods = useForm();
    const { register, handleSubmit, errors } = methods;
    const onSubmit = data => console.log(data);

    return (
    <FormProvider {...methods} > // pass all methods into the context
        <form onSubmit={handleSubmit(onSubmit)}>
        <label htmlFor="name">Name</label>
        <input type="text" id="name" name="name" ref={register({ required: true, maxLength: 30 })} />
        {errors.name amp;amp; errors.name.type === "required" amp;amp; <span>This is required</span>}
        {errors.name amp;amp; errors.name.type === "maxLength" amp;amp; <span>Max length exceeded</span> }
        <NestedComponent1 />
        <input type="submit" />
        </form>
    </FormProvider>
    );
}

function NestedComponent1() {
    const { register } = useFormContext(); // retrieve all hook methods
    
    return (
        <div>
            <input {...register("nestedName")} type="text" id="nested-name" name="nestedName"  />
            <input {...register("nestedName2")} type="text" id="nested-name2" name="nestedName2" />
            <input {...register("nestedName3")} type="text" id="nested-name3" name="nestedName3" />
        </div>
    );
}

 

Ответ №2:

Чтобы извлечь ваши данные из вложенных компонентов, вы можете добавить «useState» в свой тестовый компонент и передать функцию onChange вложенным компонентам.

 import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, errors } = useForm();
  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="name">A</label>
      <input
        type="text"
        id="name"
        name="name"
        ref={register({ required: true, maxLength: 30 })}
      />
      {errors.name amp;amp; errors.name.type === "required" amp;amp; (
        <span>This is required</span>
      )}
      {errors.name amp;amp; errors.name.type === "maxLength" amp;amp; (
        <span>Max length exceeded</span>
      )}
      <NestedComponent1 register={register} />
      <NestedComponent2 register={register} />
      <input type="submit" />
    </form>
  );
}

function NestedComponent1({register}) {
  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      <label htmlFor="nestedName">B</label>
      <input type="text" id="nested-name" name="nestedName" ref={register} />
      <label htmlFor="nesteNamename2">C</label>
      <input type="text" id="nested-name2" name="nestedName2" ref={register} />
      <label htmlFor="nestedName3">D</label>
      <input type="text" id="nested-name3" name="nestedName3" ref={register} />
    </div>
  );
}

function NestedComponent2({ register }) {
  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      <label htmlFor="nestedcomp2Name">E</label>
      <input
        type="text"
        id="nested-comp2-name"
        name="nestedcomp2Name"
        ref={register}
      />
      <label htmlFor="nestedcomp2Name2">F</label>
      <input
        type="text"
        id="nested-comp2-name2"
        name="nestedcomp2Name2"
        ref={register}
      />
      <label htmlFor="nestedcomp2Name3">G</label>
      <input
        type="text"
        id="nested-comp2-name3"
        name="nestedcomp2Name3"
        ref={register}
      />
    </div>
  );
}
 

Комментарии:

1. Не можем ли мы сделать то же самое через React-hook-form ? Я имею в виду, нет ли у нас способа просто использовать это для сбора всех данных вложенных полей? потому что, когда я нажимаю отправить, я хочу, чтобы данные полей считывались формой подключения с реакцией

2. Я изменил свой ответ, проверьте выше. Все, что вам нужно сделать, это отправить метод регистрации дочерним элементам. Также ознакомьтесь с официальными документами react-hook-form: react-hook-form.com/advanced-usage

3. react-hook-form.com/advanced-usage это может быть полезно

4. Это было единственное решение, которое хорошо работало для меня.