在 Next.js 中将函数作为 props 传递

Passing a function as props in Next.js

我正在尝试将函数 submitForm 从 formControl 传递到 index.js (Home)。我的目标:在成功提交表单后删除表单并显示成功消息。我看了几个例子,但我仍然遗漏了一些东西。

我正在使用 Next.js,但我认为 Next.js 的用法与本例中的 react.js 没有任何不同。同样使用 react-hook-form,我不认为 RHF 会中断这个过程。

index.js首页视图

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@provider.com" 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;

Next.js 只是 React 之上的逻辑,因此您与它交互的方式对两个库的处理方式相同。

但是,React 和 Next.js 中的页面都是组件,但是 Next.js 中的页面具有很多功能 added/injected,因此您必须区别对待它们。

因此,您不能只传递 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

话虽如此,您可以使用 react-hook-form 的 successful form submission 状态来简化表单状态。

export default function Home() {
  const {formState: { isSubmitSuccessful } } = useForm();

  if(isSubmitSuccessful) return <h2>Your from was submitted</h2>;

  <form onSubmit={handleSubmit((onSubmit))}>
   ...form stuff
  </form>
}

您也可以将表单设为自己的组件

首页

import HomeForm form './HomeForm'

export default function Home() {
 handleSubmit= () => {...submit logic}
 return <HomeForm onSubmit={handleSubmit} />
}

主页表单组件

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>
}