【问题标题】:react-select not showing default value and not updatingreact-select 不显示默认值且不更新
【发布时间】:2022-01-23 02:27:38
【问题描述】:

我想用 select 做一个表格。我使用钩子并为此使用 react-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>
  );
}

【问题讨论】:

    标签: reactjs forms react-hooks next.js react-select


    【解决方案1】:

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

    回调可能如下所示。

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

    然后,修改SelectFieldRequired 的onChange 属性来接收它。

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

    Codesandbox 中的最小工作示例:https://codesandbox.io/s/bold-oskar-d1in0

    【讨论】:

    • 对不起,我是第一次使用钩子,我不明白我必须在哪里插入 const onChange...
    • 我有一个错误:“服务器错误 ReferenceError: options is not defined” 当我写:“ const [form, setForm] = useState({ lastName: "", to_name: "service_ ........", firstName: "", company: "", phone: "", email: "", natureOfTheRequest: options[1], message: "", acceptCGU: false, }); "
    • @steph 我已经用完整的代码示例更新了我的答案,以便澄清。
    • 抱歉,问题总是一样...我已经用所有代码更新了我的问题,也许错误来自其他地方...
    • @steph SelectFieldRequired 道具必须是一个对象,你也错过了。检查我更新的答案。另外,这里有一个 codesanbox 中的最小工作示例:codesandbox.io/s/bold-oskar-d1in0?file=/components/…。
    猜你喜欢
    • 2021-02-12
    • 2021-07-29
    • 2021-11-28
    • 2018-09-16
    • 1970-01-01
    • 2019-07-13
    • 2019-08-22
    • 1970-01-01
    • 2014-09-03
    相关资源
    最近更新 更多