#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. будьте осторожны с обработчиком в контексте и запомните его, иначе дочерний компонент всегда будет повторно отображаться при каждом изменении родителей.