I wrote the Code and it has a separate script file, but when I click on the button next or before, the nextPrev does not work , I have put all the JS codes into the useEffect and I don't know if this method is correct or not
i can't read function inside in useEffect
and show me this error:
Line 174:57: 'nextPrev' is not defined no-undef
const AddTest = () => {
useEffect(()=>{
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the current tab
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("step");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == (x.length - 1)) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n)
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("step");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab n;
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("signUpForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("step");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i ) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className = " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("stepIndicator")[currentTab].className = " finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i, x = document.getElementsByClassName("stepIndicator");
for (i = 0; i < x.length; i ) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className = " active";
}
},[])
return (
<>
<div className="row">
<p>njjj</p>
<form id="signUpForm" className="md-12" action="#!">
<div className="form-header d-flex mb-4">
<span className="stepIndicator">تنظیمات</span>
<span className="stepIndicator">سوالات</span>
<span className="stepIndicator">تفسیر</span>
<span className="stepIndicator">پیش نمایش</span>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="form-row">
<div className="col-md-6 mb-3">
<input type="text" className="form-control" id="validationCustom01" placeholder="First name" required />
</div>
<div className="col-md-6 mb-3">
<input type="text" className="form-control" id="validationCustom02" placeholder="Last name" required />
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<textarea className="form-control"></textarea>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<input type="text" className="form-control" id="validationCustom01" placeholder="First name" required />
</div>
</div>
<div className="form-group">
<label for="company_name" className="font-weight-bold text-right">درصد افیلیت</label>
<p className="text-muted">درصدی از هزینه تست که میخواهید به پزشک یا نمایندگان اختصاص داده شود را تعیین کنید.</p>
<div className="form-row">
<div className="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline1" name="customRadioInline1" className="custom-control-input" />
<label className="custom-control-label" for="customRadioInline1">5 درصد</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline2" name="customRadioInline1" className="custom-control-input" />
<label className="custom-control-label" for="customRadioInline2">10 درصد</label>
</div>
</div>
</div>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="mb-3">
<input type="email" placeholder="Email Address" oninput="this.className = ''" name="email" />
</div>
<div className="mb-3">
<input type="password" placeholder="Password" oninput="this.className = ''" name="password" />
</div>
<div className="mb-3">
<input type="password" placeholder="Confirm Password" oninput="this.className = ''" name="password" />
</div>
</div>
<div className="step">
<p className="text-center mb-4">Your presence on the social network</p>
<div className="mb-3">
<input type="text" placeholder="Linked In" oninput="this.className = ''" name="linkedin" />
</div>
<div className="mb-3">
<input type="text" placeholder="Twitter" oninput="this.className = ''" name="twitter" />
</div>
<div className="mb-3">
<input type="text" placeholder="Facebook" oninput="this.className = ''" name="facebook" />
</div>
</div>
<div className="step">
<p className="text-center mb-4">We will never sell it</p>
<div className="mb-3">
<input type="text" placeholder="Full name" oninput="this.className = ''" name="fullname" />
</div>
<div className="mb-3">
<input type="text" placeholder="Mobile" oninput="this.className = ''" name="mobile" />
</div>
<div className="mb-3">
<input type="text" placeholder="Address" oninput="this.className = ''" name="address" />
</div>
</div>
<div className="form-footer d-flex">
<button type="button" id="prevBtn" onClick="nextPrev(-1)">Previous</button>
<button type="button" id="nextBtn" onClick="nextPrev(1)">Next</button>
</div>
</form>
</div>
</>
);
};
export default AddTest;
CodePudding user response:
Respectfully, your code is quite confusing the read. If you are using React, then use React! Someone else provided you with a Code Sandbox, but here is yet another.
Pay attention at how, with React, you have no need to use document.getElementById
, etc. If you need a reference to a DOMElement, then use useRef
(e.g. <div ref={ ref } ... />
, accessible via ref.current
).
import { useState } from "react";
import classnames from "classnames";
const DEFAULT_FORM_DATA = {
firstName: "",
lastName: "",
notes: "",
radioValue: 0, // ????
email: "",
password: "",
passwordConfirm: "",
address: "",
mobile: "",
linkedin: "",
twitter: "",
facebook: ""
};
const AddTest = () => {
// Current tab is set to be the first tab (0)
const [currentTab, setCurrentTab] = useState(0);
const [formData, setFormData] = useState(DEFAULT_FORM_DATA);
const [formValid, setFormValid] = useState({});
const handleInputChange = (e) => {
const key = e.target.name;
const value = e.target.value;
const valid = value !== "";
setFormValid((formValid) => ({ ...formValid, [key]: valid }));
setFormData((formData) => ({ ...formData, [key]: value }));
};
const handlePreviousTab = () =>
setCurrentTab((currentTab) => Math.max(currentTab - 1, 0));
const handleNextTab = () =>
setCurrentTab((currentTab) => Math.min(currentTab 1, 3));
const handleSubmit = () => {
console.log("TODO : submit formData = ", formData);
};
return (
<>
<div className="row">
<p>njjj</p>
<form id="signUpForm" className="md-12" action="#!">
<div className="form-header d-flex mb-4">
<span
className={classnames("stepIndicator", {
active: currentTab === 0
})}
>
تنظیمات
</span>
<span
className={classnames("stepIndicator", {
active: currentTab === 1
})}
>
سوالات
</span>
<span
className={classnames("stepIndicator", {
active: currentTab === 2
})}
>
تفسیر
</span>
<span
className={classnames("stepIndicator", {
active: currentTab === 3
})}
>
پیش نمایش
</span>
</div>
<div
className="step"
style={{ display: currentTab === 0 ? "" : "none" }}
>
<p className="text-center mb-4">Create your account</p>
<div className="form-row">
<div className="col-md-6 mb-3">
<input
type="text"
className={classnames("form-control", {
invalid: formValid.firstName === false
})}
name="firstName"
placeholder="First name"
required
value={formData.firstName}
onChange={handleInputChange}
/>
</div>
<div className="col-md-6 mb-3">
<input
type="text"
className={classnames("form-control", {
invalid: formValid.lastName === false
})}
name="lastName"
placeholder="Last name"
required
value={formData.lastName}
onChange={handleInputChange}
/>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<textarea
className="form-control"
name="notes"
value={formData.notes}
onChange={handleInputChange}
></textarea>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<input
type="text"
className={classnames("form-control", {
invalid: formValid.firstName === false
})}
name="firstName"
placeholder="First name"
required
value={formData.firstName}
onChange={handleInputChange}
/>
</div>
</div>
<div className="form-group">
<label
htmlFor="company_name"
className="font-weight-bold text-right"
>
درصد افیلیت
</label>
<p className="text-muted">
درصدی از هزینه تست که میخواهید به پزشک یا نمایندگان اختصاص داده
شود را تعیین کنید.
</p>
<div className="form-row">
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
name="radioValue"
className="custom-control-input"
value={5}
checked={formData.radioValue === "5"}
onChange={handleInputChange}
/>
<label
className="custom-control-label"
htmlFor="customRadioInline1"
>
5 درصد
</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
name="radioValue"
className="custom-control-input"
value={10}
checked={formData.radioValue === "10"}
onChange={handleInputChange}
/>
<label
className="custom-control-label"
htmlFor="customRadioInline2"
>
10 درصد
</label>
</div>
</div>
</div>
</div>
<div
className="step"
style={{ display: currentTab === 1 ? "" : "none" }}
>
<p className="text-center mb-4">Create your account</p>
<div className="mb-3">
<input
type="email"
placeholder="Email Address"
onInput={(e) => (e.target.className = "")}
name="email"
value={formData.email}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Password"
onInput={(e) => (e.target.className = "")}
name="password"
value={formData.password}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Confirm Password"
onInput={(e) => (e.target.className = "")}
name="passwordConfirm"
value={formData.passwordConfirm}
onChange={handleInputChange}
/>
</div>
</div>
<div
className="step"
style={{ display: currentTab === 2 ? "" : "none" }}
>
<p className="text-center mb-4">
Your presence on the social network
</p>
<div className="mb-3">
<input
type="text"
placeholder="Linked In"
onInput={(e) => (e.target.className = "")}
name="linkedin"
value={formData.linkedin}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Twitter"
onInput={(e) => (e.target.className = "")}
name="twitter"
value={formData.twitter}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Facebook"
onInput={(e) => (e.target.className = "")}
name="facebook"
value={formData.facebook}
onChange={handleInputChange}
/>
</div>
</div>
<div
className="step"
style={{ display: currentTab === 3 ? "" : "none" }}
>
<p className="text-center mb-4">We will never sell it</p>
<div className="mb-3">
<input
type="text"
placeholder="Full name"
onInput={(e) => (e.target.className = "")}
name="fullname"
value={formData.fullname}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Mobile"
onInput={(e) => (e.target.className = "")}
name="mobile"
value={formData.mobile}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Address"
onInput={(e) => (e.target.className = "")}
name="address"
value={formData.address}
onChange={handleInputChange}
/>
</div>
</div>
<div className="form-footer d-flex">
<button
type="button"
id="prevBtn"
onClick={handlePreviousTab}
style={{ display: currentTab > 0 ? "" : "none" }}
>
Previous
</button>
<button
type="button"
id="nextBtn"
onClick={currentTab === 3 ? handleSubmit : handleNextTab}
>
{currentTab === 3 ? "Submit" : "Next"}
</button>
</div>
</form>
</div>
</>
);
};
export default AddTest;
Consider watching or reading some tutorials on using React, and then try to adopt best practices when using the framework. This will not only make your code easier to read for others, it will help you actually use the framework how it is intended.
Note
The "next" button may become a submit button if you want to submit the form through the browser instead of manually handling it. If this is the intention, you could change the button with
<button
type={ currentTab === 3 ? "submit", : "button" }
id="nextBtn"
onClick={currentTab === 3 ? null : handleNextTab}
>
{currentTab === 3 ? "Submit" : "Next"}
</button>
CodePudding user response:
Try this, I set currentTab
as a state so I think you don't need to worry about useEffect:
import { useState } from "react";
const AddTest = () => {
const [currentTab, setCurrentTab] = useState(0);
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("step");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == x.length - 1) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n);
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("step");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
setCurrentTab(currentTab n);
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("signUpForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x,
y,
i,
valid = true;
x = document.getElementsByClassName("step");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i ) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className = " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("stepIndicator")[currentTab].className =
" finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i,
x = document.getElementsByClassName("stepIndicator");
for (i = 0; i < x.length; i ) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className = " active";
}
useEffect(() => {
showTab(currentTab); // Display the current tab
}, []);
return (
<>
<div className="row">
<p>njjj</p>
<form id="signUpForm" className="md-12" action="#!">
<div className="form-header d-flex mb-4">
<span className="stepIndicator">تنظیمات</span>
<span className="stepIndicator">سوالات</span>
<span className="stepIndicator">تفسیر</span>
<span className="stepIndicator">پیش نمایش</span>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="form-row">
<div className="col-md-6 mb-3">
<input
type="text"
className="form-control"
id="validationCustom01"
placeholder="First name"
required
/>
</div>
<div className="col-md-6 mb-3">
<input
type="text"
className="form-control"
id="validationCustom02"
placeholder="Last name"
required
/>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<textarea className="form-control"></textarea>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<input
type="text"
className="form-control"
id="validationCustom01"
placeholder="First name"
required
/>
</div>
</div>
<div className="form-group">
<label for="company_name" className="font-weight-bold text-right">
درصد افیلیت
</label>
<p className="text-muted">
درصدی از هزینه تست که میخواهید به پزشک یا نمایندگان اختصاص داده
شود را تعیین کنید.
</p>
<div className="form-row">
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="customRadioInline1"
name="customRadioInline1"
className="custom-control-input"
/>
<label
className="custom-control-label"
for="customRadioInline1"
>
5 درصد
</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="customRadioInline2"
name="customRadioInline1"
className="custom-control-input"
/>
<label
className="custom-control-label"
for="customRadioInline2"
>
10 درصد
</label>
</div>
</div>
</div>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="mb-3">
<input
type="email"
placeholder="Email Address"
oninput="this.className = ''"
name="email"
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Password"
oninput="this.className = ''"
name="password"
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Confirm Password"
oninput="this.className = ''"
name="password"
/>
</div>
</div>
<div className="step">
<p className="text-center mb-4">
Your presence on the social network
</p>
<div className="mb-3">
<input
type="text"
placeholder="Linked In"
oninput="this.className = ''"
name="linkedin"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Twitter"
oninput="this.className = ''"
name="twitter"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Facebook"
oninput="this.className = ''"
name="facebook"
/>
</div>
</div>
<div className="step">
<p className="text-center mb-4">We will never sell it</p>
<div className="mb-3">
<input
type="text"
placeholder="Full name"
oninput="this.className = ''"
name="fullname"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Mobile"
oninput="this.className = ''"
name="mobile"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Address"
oninput="this.className = ''"
name="address"
/>
</div>
</div>
<div className="form-footer d-flex">
<button type="button" id="prevBtn" onclick={() => nextPrev(-1)}>
Previous
</button>
<button type="button" id="nextBtn" onclick={() => nextPrev(1)}>
Next
</button>
</div>
</form>
</div>
</>
);
};
export default AddTest;
CodePudding user response:
const AddTest = () => {
const [currentTab, setCurrentTab] = React.useState(0);
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i,
x = document.getElementsByClassName("stepIndicator");
for (i = 0; i < x.length; i ) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className = " active";
}
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("step");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == x.length - 1) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n);
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("step");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
setCurrentTab((curTab) => curTab n);
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("signUpForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x,
y,
i,
valid = true;
x = document.getElementsByClassName("step");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i ) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className = " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("stepIndicator")[currentTab].className =
" finish";
}
return valid; // return the valid status
}
useEffect(() => {
showTab(currentTab); // Display the current tab
}, []);
return (
<>
<div className="row">
<p>njjj</p>
<form id="signUpForm" className="md-12" action="#!">
<div className="form-header d-flex mb-4">
<span className="stepIndicator">تنظیمات</span>
<span className="stepIndicator">سوالات</span>
<span className="stepIndicator">تفسیر</span>
<span className="stepIndicator">پیش نمایش</span>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="form-row">
<div className="col-md-6 mb-3">
<input
type="text"
className="form-control"
id="validationCustom01"
placeholder="First name"
required
/>
</div>
<div className="col-md-6 mb-3">
<input
type="text"
className="form-control"
id="validationCustom02"
placeholder="Last name"
required
/>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<textarea className="form-control"></textarea>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<input
type="text"
className="form-control"
id="validationCustom01"
placeholder="First name"
required
/>
</div>
</div>
<div className="form-group">
<label for="company_name" className="font-weight-bold text-right">
درصد افیلیت
</label>
<p className="text-muted">
درصدی از هزینه تست که میخواهید به پزشک یا نمایندگان اختصاص داده
شود را تعیین کنید.
</p>
<div className="form-row">
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="customRadioInline1"
name="customRadioInline1"
className="custom-control-input"
/>
<label
className="custom-control-label"
for="customRadioInline1"
>
5 درصد
</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="customRadioInline2"
name="customRadioInline1"
className="custom-control-input"
/>
<label
className="custom-control-label"
for="customRadioInline2"
>
10 درصد
</label>
</div>
</div>
</div>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="mb-3">
<input
type="email"
placeholder="Email Address"
oninput="this.className = ''"
name="email"
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Password"
oninput="this.className = ''"
name="password"
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Confirm Password"
oninput="this.className = ''"
name="password"
/>
</div>
</div>
<div className="step">
<p className="text-center mb-4">
Your presence on the social network
</p>
<div className="mb-3">
<input
type="text"
placeholder="Linked In"
oninput="this.className = ''"
name="linkedin"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Twitter"
oninput="this.className = ''"
name="twitter"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Facebook"
oninput="this.className = ''"
name="facebook"
/>
</div>
</div>
<div className="step">
<p className="text-center mb-4">We will never sell it</p>
<div className="mb-3">
<input
type="text"
placeholder="Full name"
oninput="this.className = ''"
name="fullname"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Mobile"
oninput="this.className = ''"
name="mobile"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Address"
oninput="this.className = ''"
name="address"
/>
</div>
</div>
<div className="form-footer d-flex">
<button type="button" id="prevBtn" onClick={() => nextPrev(-1)}>
Previous
</button>
<button type="button" id="nextBtn" onClick={() => nextPrev(1)}>
Next
</button>
</div>
</form>
</div>
</>
);
};
export default AddTest;
CodePudding user response:
I created this CodeSandBox to guide you in the react way. I only added handling the next and prev steps. https://codesandbox.io/s/keen-feather-cr801y?file=/src/App.js
It's better to read about form handling: https://www.w3schools.com/react/react_forms.asp https://ibaslogic.com/simple-guide-to-react-form/
Or you can use a package like formik to help.