Home > Software engineering >  react-select not showing default value and not updating
react-select not showing default value and not updating

Time:12-25

I would like to do a form with select. I use hooks and I use react-select for this.

My problems: The field select doesn't show the default value. When I select value the field don't show it. When I click on submit button, no value are send.

I don't understand why, could someone help me please?

This is my code:

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

CodePudding user response:

You're setting the Select value to form.natureOfTheRequest, so you need to update that specific field on its onChange callback, rather than simply passing setForm.

The callback could look like the following.

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

Then, modify the SelectFieldRequired's onChange prop to receive it.

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

Since you're explicitly setting the value on the Select, that also overrides the defaultValue you have set. Instead, you can set the form.natureOfTheRequest initial value to options[1].

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

You also need to change the SelectFieldRequired component signature, as the props have to be destructured from the props object.

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

Full code example:

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

Minimal working example in Codesandbox: https://codesandbox.io/s/bold-oskar-d1in0

  • Related