Reputation: 73
I am attempting to pass the function submitForm from formControl to index.js (Home). My goal: to remove form, upon successful form submission and show a success message. I have looked at several examples, but I am still missing something.
I am using Next.js, but I don't think the Next.js usage would be any different from react.js in this case. Also using react-hook-form, once again, I don't think RHF is interrupting the process.
index.js Home view
import { useState } from 'react';
import { useForm } from "react-hook-form";
import styles from '../styles/Home.module.css'
import { proteinArr, starchArr, greensArr} from '../utils'
import date from 'date-and-time';
export default function Home({ submitForm }) {
const { register, handleSubmit, control, formState: { errors } } = useForm();
const onSubmit = (data, e) => {
e.target.reset()
submitForm()
}
const now = new Date();
let day = date.format(now, 'dddd').toLowerCase();
// console.log(SaturdayArr)
// console.log(date.format(now, 'dddd').toLowerCase())
return (
<>
<form onSubmit={handleSubmit((onSubmit))}>
<div className={`${styles.home_card} card home_card `}>
<div className="card-body">
<h2 className={styles.title}>Pick your plate!</h2>
<div className={`${styles.home_selectGroup} input-group mb-3`}>
<div className="input-group-prepend">
<span className="input-group-text" >Name</span>
</div>
<input type="text" className="form-control" {...register("name", { required: true })} placeholder="Order Name" aria-label="Order Name" aria-describedby="basic-addon" />
{errors.name && <p>Order name is required</p>}
</div>
<div className={`${styles.home_selectGroup} input-group mb-3`}>
<div className="input-group-prepend">
<span className="input-group-text" >Email</span>
</div>
<input type="email" id="email" className="form-control" {...register("email")} placeholder="[email protected]" aria-label="Email" aria-describedby="basic-addon" />
</div>
<div className={`${styles.home_selectGroup} input-group mb-3`}>
<div className="input-group-prepend">
<span className="input-group-text" >Phone Number</span>
</div>
<input type="tel" id="phone" className="form-control" {...register("phone", { required: true })} placeholder="111-111-1111" aria-label="Phone Number" aria-describedby="basic-addon" />
{errors.name && <p>Phone number is required</p>}
</div>
<div className={`${styles.home_selectGroup} input-group mb-3`}>
<div className="input-group-prepend">
<label className={`${styles.homeLabel} input-group-text`} htmlFor="inputGroupSelect01">Protein</label>
</div>
<select {...register("protein", { required: true })}
className={`${styles.home_select} custom-select" id="inputGroupSelect01`}
>
<option className={styles.home_option}>Choose...</option>
{proteinArr && proteinArr.map((item) => <option key={item}>{item}</option>)}
</select>
{errors.protein && <p>Protein is required</p>}
</div>
<div className={`${styles.home_selectGroup} input-group mb-3`}>
<div className="input-group-prepend">
<label className={`${styles.homeLabel} input-group-text`} htmlFor="inputGroupSelect01">Greens</label>
</div>
<select
{...register("greens", { required: 'select an option' })}
className={`${styles.home_select} custom-select" id="inputGroupSelect01`}>
<option className={styles.home_option}>Choose...</option>
{greensArr && greensArr.map((item) => <option key={item}>{item}</option>)}
</select>
{errors.greens && <p>Green is required</p>}
</div>
<div className={`${styles.home_selectGroup} input-group mb-3`}>
<div className="input-group-prepend">
<label className={`${styles.homeLabel} input-group-text`} htmlFor="inputGroupSelect01">Starch</label>
</div>
<select {...register("starch", { required: true })} className={`${styles.home_select} custom-select" id="inputGroupSelect01`}>
<option className={styles.home_option}>Choose...</option>
{starchArr && starchArr.map((item) => <option key={item}>{item}</option>)}
</select>
{errors.starch && <p>Starch is required</p>}
</div>
<button className="btn btn-primary contact-form_button " type="submit">Submit My Order</button>
</div>
</div>
</form>
</>
)
}
FormControl
import Home from '../../pages/index'
import { useState } from 'react';
const FormControl = () => {
const [isSubmitted, setIsSubmitted] = useState(false);
function submitForm(){
setIsSubmitted(true);
}
return (
<div>
{isSubmitted == false ? <Home submitForm={submitForm}/> : <h2>Your from was submitted</h2>}
</div>
);
}
export default FormControl;
Upvotes: 3
Views: 13283
Reputation: 6608
Next.js is just logic on top of React so the way you interact with it is handled the same for both libraries.
However, pages in React and Next.js are both components but pages in Next.js have a lot of functionality added/injected, so you must treat them differently.
Because of this, you cannot just pass props to pages in Next.js like you are as they will always be undefined. You can set page props via getInitialProps, getStaticProps, getServerSideProps, in _document, or even in _app.
With that said, you can simplify your form status by using react-hook-form's successful form submission status.
export default function Home() {
const {formState: { isSubmitSuccessful } } = useForm();
if(isSubmitSuccessful) return <h2>Your from was submitted</h2>;
<form onSubmit={handleSubmit((onSubmit))}>
...form stuff
</form>
}
You could make the form it's own component too
Home page
import HomeForm form './HomeForm'
export default function Home() {
handleSubmit= () => {...submit logic}
return <HomeForm onSubmit={handleSubmit} />
}
Home form component
export default function HomeForm({ onSubmit }) {
const {formState: { isSubmitSuccessful } } = useForm();
if(isSubmitSuccessful) return <h2>Your from was submitted</h2>;
<form onSubmit={handleSubmit((onSubmit))}>
...form stuff
</form>
}
Upvotes: 3