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

Posted

技术标签:

【中文标题】react-select 不显示默认值且不更新【英文标题】:react-select not showing default value and not updating 【发布时间】: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.-]?\d2)4|\d2(?:[\s.-]?\d3)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>
  );

【问题讨论】:

【参考方案1】:

您将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>
    );

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/…。

以上是关于react-select 不显示默认值且不更新的主要内容,如果未能解决你的问题,请参考以下文章

react-select 默认值设置但未突出显示

reactcarousel走马灯eacharts最后一个不显

react-select:禁用默认样式

在定义自定义选项组件时,如何为react-select应用默认样式?

添加具有空字符串作为默认值且非空约束的列会导致 oracle 数据库的行为不一致

如何在 react-select 中设置默认值