react-select 不显示默认值且不更新

react-select not showing default value and not updating

我想用 select 做一个表格。我使用钩子,为此我使用 react-select。

我的问题: 字段 select 不显示默认值。 当我 select 值字段不显示它。 当我点击提交按钮时,没有发送任何值。

我不明白为什么,有人可以帮助我吗?

这是我的代码:

import React, { useState } from "react";
import emailjs from "emailjs-com";
import styles from "../../styles/ContactForm.module.scss";
import Select from 'react-select'

function Field({ name, value, onChange, children }) {
  return (
    <div className="form-group mb-2">
      <label htmlFor={name}>{children}</label>
      <input
        type="text"
        value={value}
        onChange={onChange}
        id={name}
        name={name}
        className="form-control"
      />
    </div>
  );
}
function FieldRequired({ name, value, onChange, children }) {
  return (
    <div className="form-group mb-2">
      <label htmlFor={name}>{children}</label>
      <input
        type="text"
        value={value}
        onChange={onChange}
        required
        id={name}
        name={name}
        className="form-control"
      />
    </div>
  );
}
function FieldTel({ name, value, onChange, children }) {
  return (
    <div className="form-group mb-2">
      <label htmlFor={name}>{children}</label>
      <input
        type="tel"
        pattern="^(?:(?:\+|00)33[\s.-]{0,3}(?:\(0\)[\s.-]{0,3})?|0)[1-9](?:(?:[\s.-]?\d{2}){4}|\d{2}(?:[\s.-]?\d{3}){2})$"
        value={value}
        onChange={onChange}
        id={name}
        name={name}
        className="form-control"
      />
      <small className="form-text text-muted">
        Votre téléphone servira uniquement a vous contacter pour votre demande.
      </small>
    </div>
  );
}
function CheckBox({ name, value, onChange, children }) {
  return (
    <div className="form-check mb-2">
      <input
        type="checkbox"
        checked={value}
        onChange={onChange}
        id={name}
        name={name}
        required
        className="form-check-input"
      />
      <label htmlFor={name} className="form-check-label">
        {children}
      </label>
    </div>
  );
}
function EmailBox({ name, value, onChange, children }) {
  return (
    <div className="form-group mb-2">
      <label htmlFor={name}>{children}</label>
      <input
        type="email"
        pattern="^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"
        value={value}
        onChange={onChange}
        required
        id={name}
        name={name}
        className="form-control"
      />
      <small className="form-text text-muted">
        Votre email servira uniquement a vous contacter pour votre demande.
      </small>
    </div>
  );
}
function TextArea({ name, value, onChange, children }) {
  return (
    <div className="form-group mb-2">
      <label htmlFor={name}>{children}</label>
      <textarea
        rows="3"
        maxLength="2000"
        value={value}
        onChange={onChange}
        id={name}
        name={name}
        className="form-control"
      />
    </div>
  );
}

let options = [
  {value: "vitrine-cms", label: "Site vitrine CMS"},
  {value: "vitrine-main", label: "Site vitrine sur-mesure"},
  {value: "eCommerce", label: "Site eCommerce"},
  {value: "autre-site", label: "Autre site"},
  {value: "ponctuel", label: "Mission ponctuelle"},
  {value: "maintenance", label: "Maintenance"},
  {value: "autre", label: "Autre choix"},
]

function SelectFieldRequired(name, value, onChange) {
  return( 
    <>
      <div>Nature de la demande</div>
      <Select
            name={name}
            value={value}
            defaultValue={options[1]}
            onChange={onChange}
            options={options}
      />    
    </>
  )
}

export default function ContactForm() {
  const [form, setForm] = useState({
    lastName: "",
    to_name: "service_.....",
    firstName: "",
    company: "",
    phone: "",
    email: "",
    natureOfTheRequest: options[1],
    message: "",
    acceptCGU: false,
  });
  const sendEmail = (e) => {
    e.preventDefault();

    emailjs
      .sendForm(
        "service_....",
        "template_.....",
        e.target,
        "user_......"
      )

      .then(
        (result) => {
          console.log(result);
          alert("Email bien envoyé!!!");
        },
        (error) => {
          console.log(error);
        }
      );
      
    e.target.reset();
  };
  const onChange = (value) => {
    setForm((prevForm) => ({
        ...prevForm,
        natureOfTheRequest: value
    }));
};


  return (
    <div className="container">
      <form onSubmit={sendEmail}>
        {/* ............................................................................................ */}
        <FieldRequired name="lastName" value={form.lastName} onChange={setForm}>
          Nom *
        </FieldRequired>
        {/* ............................................................................................ */}
        <Field name="firstName" value={form.firstName} onChange={setForm}>
          Prénom
        </Field>
        {/* ............................................................................................ */}
        <Field name="company" value={form.company} onChange={setForm}>
          Société
        </Field>
        {/* ............................................................................................ */}
        <FieldTel name="phone" value={form.phone} onChange={setForm}>
          Téléphone
        </FieldTel>
        {/* ............................................................................................ */}
        <EmailBox name="email" value={form.email} onChange={setForm}>
          Email *
        </EmailBox>
        {/* ............................................................................................ */}
         <SelectFieldRequired 
          className="request col-12" 
          name="natureOfTheRequest" 
          value={form.natureOfTheRequest} 
          onChange={onChange}
          id="natureOfTheRequest" 
        />
{/*         <div className="form-group  mb-2">
          <label className="request col-12" htmlFor="request">
            Nature de la demande *
          </label>
          <select
            id="natureOfTheRequest"
            name="natureOfTheRequest"
            onChange={setForm}
            value={form.natureOfTheRequest}
            required
            className="py-1 rounded-3"
          >
            <option value="">Sélectionnez</option>
            <option value="vitrine-cms">Site vitrine Wordpress</option>
            <option value="vitrine-main">Site vitrine sur-mesure</option>
            <option value="eCommerce">Site E-Commerce CMS</option>
            <option value="autre-site">Autre site sur-mesure</option>
            <option value="ponctuel">Travail ponctuel</option>
            <option value="maintenance">Maintenance</option>
            <option value="autre">Autre sujet</option>
          </select>
        </div>
 */}        {/* ............................................................................................ */}
        <TextArea name="message" value={form.message} onChange={setForm}>
          Explication sur votre demande
        </TextArea>
        {/* ............................................................................................ */}
        {/* ............................................................................................ */}
        <CheckBox name="acceptCGU" value={form.acceptCGU} onChange={setForm}>
          J&apos;accepte que mes données soient utilisées pour me contacter *
        </CheckBox>
        {/* ............................................................................................ */}
        {/* SUBMIT button */}
        <button
          type="submit"
          id={styles.submitButton}
          className="btn btn-primary"
        >
          {" "}
          Envoyer le formulaire
        </button>
      </form>
    </div>
  );
}

您将 Select 值设置为 form.natureOfTheRequest,因此您需要在其 onChange 回调中更新该特定字段,而不是简单地传递 setForm

回调可能如下所示。

const onChange = (value) => {
    setForm((prevForm) => ({
      ...prevForm,
      natureOfTheRequest: value
    }));
};

然后,修改SelectFieldRequiredonChange道具来接收它。

<SelectFieldRequired 
    className="request col-12" 
    name="natureOfTheRequest" 
    value={form.natureOfTheRequest} 
    onChange={onChange}
    id="natureOfTheRequest" 
/>

由于您在 Select 上明确设置了值,这也会覆盖您设置的 defaultValue。相反,您可以将 form.natureOfTheRequest 初始值设置为 options[1].

const [form, setForm] = useState({
    lastName: "",
    to_name: "service_........",
    firstName: "",
    company: "",
    phone: "",
    email: "",
    natureOfTheRequest: options[1],
    message: "",
    acceptCGU: false,
});

您还需要更改 SelectFieldRequired 组件签名,因为道具必须从 props 对象中解构。

function SelectFieldRequired({ name, value, onChange }) {
    //...
}

完整代码示例:

let options = [
    {value: "vitrine-cms", label: "Site vitrine CMS"},
    {value: "vitrine-main", label: "Site vitrine sur-mesure"},
    {value: "eCommerce", label: "Site eCommerce"},
    {value: "autre-site", label: "Autre site"},
    {value: "ponctuel", label: "Mission ponctuelle"},
    {value: "maintenance", label: "Maintenance"},
    {value: "autre", label: "Autre choix"},
]

// Change props to an object with fields here
function SelectFieldRequired({ name, value, onChange }) {  
    return( 
      <>
         <div>Nature de la demande *</div>
         <Select
             name={name}
             value={value}
             defaultValue={options[1]}
             onChange={onChange}
             required
             options={options}
         />    
       </>
    )
}

export default function ContactForm() {
    const [form, setForm] = useState({
        lastName: "",
        to_name: "service_........",
        firstName: "",
        company: "",
        phone: "",
        email: "",
        natureOfTheRequest: options[1],
        message: "",
        acceptCGU: false,
    });

    const sendEmail = (e) => {
        // Omitted for simplicity
    };

    const onChange = (value) => {
        setForm((prevForm) => ({
            ...prevForm,
            natureOfTheRequest: value
        }));
    };

    return (
      <div className="container">
          <form onSubmit={sendEmail}>
              <SelectFieldRequired 
                  className="request col-12" 
                  name="natureOfTheRequest" 
                  value={form.natureOfTheRequest} 
                  onChange={onChange}
                  id="natureOfTheRequest" 
              />
              {/* SUBMIT button */}
              <button
                  type="submit"
                  id={styles.submitButton}
                  className="btn btn-primary"
              >
                  {" "}
                  Envoyer le formulaire
              </button>
          </form>
      </div>
    );
}