Реакция: Можем ли мы передать 2 формы из 2 разных дочерних компонентов родительскому и отправить их с помощью кнопки, которая находится внутри родительского компонента?

#javascript #reactjs #forms #components #react-props

#язык JavaScript #реагирует на #формы #Компоненты #реагировать-реквизит

Вопрос:

Я пытаюсь каким-то образом передать данные из 2 форм и 2 разных компонентов в родительский компонент, а затем как-то консольно.регистрируйте все эти данные с помощью кнопки, расположенной внутри родительского компонента. Затем я просто отправлю эти данные в файл JSON или в фиктивную базу данных.

Когда я нажимаю кнопку «Отправить», конечно, сейчас ничего не запускается, потому что я просто не знаю, как передать функцию от детей к родителю. Я перепробовал много способов, но я был бы признателен, если бы вы могли показать мне способ поднять состояние и объединить формы. Для ввода, чтобы передать ссылки, я использовал React.forwardRef()

Было бы легко просто иметь 1 большой компонент с 1 формой, а затем кнопкой внутри этого компонента, но поскольку это интересный проект, я хочу узнать, как реализовать эту функциональность на случай, если я буду использовать ее в будущем. Вы можете найти скриншот по этой ссылке:

[] [1]: https://i.stack.imgur.com/myV0N.jpg

Вот и мы:

1. Родительский компонент

 const BookingComponent = () =gt; {  return (  lt;divgt;  lt;CRContainer className="booking-crcontainer"gt;  lt;CRColumngt;  lt;PickUpCarComponent /gt;  lt;/CRColumngt;  lt;CRColumngt;  lt;CustomerInfo /gt;  lt;/CRColumngt;  lt;/CRContainergt;  lt;CRContainer className="booking"gt;  lt;Button type="submit" btnText="hello there" /gt;  lt;/CRContainergt;  lt;/divgt;  ); };  export default BookingComponent;  

2. Ребенок 1

 const CustomerInfo = (props) =gt; {  const firstlRef = useRef();  const lastNameRef = useRef();   const onTrigger = (e) =gt; {  e.preventDefault();  //console.log(first1Ref.current.value)  console.log("heaheaheah");  };   return (  lt;gt;  lt;Subtitle stitle={SubtitleLabels.customerInfo} /gt;  lt;div className="customer-info-container"gt;  lt;form onSubmit={onTrigger}gt;  lt;divgt;  lt;LabeledInput  labelText={CustomerInfoLabels.firstName}  type="text"  inputPlaceholder={GeneralLabels.placeholder}  ref={firstlRef}  gt;lt;/LabeledInputgt;  lt;LabeledInput  labelText={CustomerInfoLabels.lastName}  type="text"  inputPlaceholder={GeneralLabels.placeholder}  ref={lastNameRef}  gt;lt;/LabeledInputgt;  lt;/divgt; ...................  

3. Ребенок 2

Я еще не поставил здесь рефери.

 const PickUpCarComponent = () =gt; {  return (  lt;divgt;  lt;Subtitle stitle={SubtitleLabels.pickUp} /gt;  lt;formgt;  lt;div className="booking-inner-container"gt;  lt;divgt;  lt;LabeledInput labelText={"Pick-up date*"} type="date"gt;lt;/LabeledInputgt;  lt;LabeledInput labelText={"Pick-up time*"} type="time"gt;lt;/LabeledInputgt;  lt;/divgt;  lt;DropDown type="CarGroup" labeltext="Car Group*" attribute="name" /gt;  lt;DropDown type="RentalOffice" labeltext="Region*" attribute="region" /gt;  lt;/divgt;  lt;/formgt;  lt;/divgt;  ); };  export default PickUpCarComponent;  

4. Входной компонент

 const LabeledInput = React.forwardRef((props, ref) =gt; {  const { labelText, type, inputPlaceholder, onChange, className } = props;   return (  lt;div className={`input-container ${className}`}gt;  lt;label htmlFor="labelText"gt;{labelText}lt;/labelgt;  lt;input  type={type}  placeholder={inputPlaceholder}  onChange={onChange}  ref={ref}  /gt;  lt;/divgt;  ); });  export default LabeledInput;  

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

1. вы можете использовать контекст в родительском компоненте и использовать его в дочерних компонентах , в этом контексте вы можете передать обработчик, который вызовет дочерний компонент. или вы можете передать обработчики событий непосредственно дочернему компоненту и обработать изменение в родительском компоненте

2. Как я мог бы реализовать вторую версию? Как я могу передать реквизит, чтобы сделать это? Не могли бы вы привести мне пример? Поскольку я знаю, как это происходит, я также упоминал об этом выше. Но мне не хватает способа его реализовать.

3. Может быть, вы могли бы дать ответ с помощью фрагмента @HDM91

Ответ №1:

вы можете использовать контекст для передачи обработчиков форм дочернему компоненту, а затем в дочернем компоненте вы можете использовать контекст, получать значения и обработчики родительской формы и использовать их.

 const FormContext = React.createContext({});  const BookingComponent = () =gt; {  const [values, setValues] = useState();    const handleChange = useCallback((e) =gt; {  //handle child event in parent and save child state in  //parent to use later in submit button  }, []); //set dependency if it's needed   const contextValue = useMemo(() =gt; ({ handleChange }), [handleChange]);   return (  lt;FormContext.Provider value={contextValue}gt;  lt;divgt;  lt;CRContainer className="booking-crcontainer"gt;  lt;CRColumngt;  lt;PickUpCarComponent /gt;  lt;/CRColumngt;  lt;CRColumngt;  lt;CustomerInfo /gt;  lt;/CRColumngt;  lt;/CRContainergt;  lt;CRContainer className="booking"gt;  lt;Button type="submit" btnText="hello there" /gt;  lt;/CRContainergt;  lt;/divgt;  lt;/FormContext.Providergt;  ); };  const LabeledInput = (props) =gt; {  const formContext = useContext(FormContext);  const { labelText, type, inputPlaceholder, className } = props;   return (  lt;div className={`input-container ${className}`}gt;  lt;label htmlFor="labelText"gt;{labelText}lt;/labelgt;  lt;input  type={type}  placeholder={inputPlaceholder}  onChange={formContext.handleChange}  ref={ref}  /gt;  lt;/divgt;  ); };  

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

1. Аааааа! Я постараюсь осуществить это завтра утром и отмечу вас. Спасибо 😀

2. будьте осторожны с обработчиком в контексте и запомните его, иначе дочерний компонент всегда будет повторно отображаться при каждом изменении родителей.