Home > front end >  How can I get radio button value in React?
How can I get radio button value in React?

Time:09-29

I have three radio buttons and I need to put the value of the selected one in inputs.reply, just like I did with inputs.name, inputs.email, inputs.phone and inputs.message. How can I do this? I know it's probably a very easy thing to do, but I've been trying for hours and it doesn't work.

import Head from 'next/head'
import React, { useState } from 'react'

export default () => {
  const [status, setStatus] = useState({
    submitted: false,
    submitting: false,
    info: { error: false, msg: null }
  })

  const [inputs, setInputs] = useState({
    reply: '',
    name: '',
    phone: '',
    email: '',
    message: ''
  })

  function SubmitButton(){
    if (inputs.name && inputs.email && inputs.message) {
      return <button type="submit" className="btn-submit" disabled={status.submitting}> {!status.submitting ? !status.submitted ? 'Submit' : 'Submitted' : 'Submitting...'} </button>
    } else {
      return <button type="submit" className="btn-submit" disabled>Submit</button>
    };
  };

  const handleResponse = (status, msg) => {
    if (status === 200) {
      setStatus({
        submitted: true,
        submitting: false,
        info: { error: false, msg: msg }
      })
      setInputs({
        reply: '',
        name: '',
        phone: '',
        email: '',
        message: ''
      })
    } else {
      setStatus({
        info: { error: true, msg: msg }
      })
    }
  }

  const handleOnChange = e => {
    e.persist()
    setInputs(prev => ({
      ...prev,
      [e.target.id]: e.target.value
    }))
    setStatus({
      submitted: false,
      submitting: false,
      info: { error: false, msg: null }
    })
  }

  const handleOnSubmit = async e => {
    e.preventDefault()
    setStatus(prevStatus => ({ ...prevStatus, submitting: true }))
    const res = await fetch('/api/send', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(inputs)
    })
    const text = await res.text()
    handleResponse(res.status, text)
  }

  return (
    <div className="contact">
      <main>
        <div className="content">
          <div>
            <h2>Get in touch!</h2>
            <h3>How can we help you?</h3>
          </div>
          <form onSubmit={handleOnSubmit}>
            <h4>How would you like us to get back to you?</h4>
            
            <div className="form-group form-group-radio">
              <div>
                <input type="radio" onChange={handleOnChange} value="Phone" name="email-reply" id="reply-phone" />  
                <label className="radio-label" htmlFor="reply-phone">Phone</label>
              </div>
              <div>
                <input type="radio" onChange={handleOnChange} value="E-mail" name="email-reply" id="reply-email" />  
                <label className="radio-label" htmlFor="reply-email">E-mail</label>
              </div>
              <div>
                <input type="radio" onChange={handleOnChange} value="No reply needed" name="email-reply" id="no-reply" />  
                <label className="radio-label" htmlFor="no-reply">No reply needed</label>
              </div>
            </div>

            <div className="form-group">
              <input
                id="name"
                type="text"
                name="name" 
                onChange={handleOnChange}
                required
                value={inputs.name}
                className={inputs.name ? "form-control active" : "form-control"}
              />
              <label className="form-label" htmlFor="name">Name</label>
            </div>

            <div className="form-group">
              <input
                id="email"
                type="text"
                name="email" 
                onChange={handleOnChange}
                required
                value={inputs.email}
                className={inputs.email ? "form-control active" : "form-control"}
              />
              <label className="form-label" htmlFor="email">Email</label>
            </div>

            <div className="form-group">
              <input
                id="phone"
                type="tel"
                name="phone" 
                onChange={handleOnChange}
                required
                value={inputs.phone}
                className={inputs.phone ? "form-control active" : "form-control"}
              />
              <label className="form-label" htmlFor="phone">Phone</label>
            </div>
            
            <div className="form-group">
              <textarea
                id="message"
                onChange={handleOnChange}
                required
                value={inputs.message}
                className={inputs.message ? "form-control active" : "form-control"}
              />
              <label className="form-label" htmlFor="message">Message</label>
            </div>

            <SubmitButton />

            {status.info.error && (
            <div className="message-feedback error">
              <p>Error: {status.info.msg}</p>
            </div>
            )}
            {!status.info.error && status.info.msg && (
              <div className="message-feedback success">
                <p>Thanks for messaging us!</p>
                <p>We'll get back to you soon.</p>
              </div>
            )}
          </form>
        </div>
      </main>
    </div>
  )
}

Thank you.

CodePudding user response:

Remove the id attribute from all of the <input type="radio" /> and instead add a name="reply" to all of them.

Now update handleOnChange, specifically this part

setInputs(prev => ({
      ...prev,
      [e.target.id || e.target.name]: e.target.value
    }))

CodePudding user response:

You can update the handleOnChange method to check for the type of the target event and if its a radio button, you can update the radio state, otherwise use the dynamic key to update the state.

const handleOnChange = (e) => {
  e.persist();
  const key = e.target.type === "radio" ? "reply" : e.target.id;
  setInputs((prev) => ({
    ...prev,
    [key]: e.target.value
  }));
  setStatus({
    submitted: false,
    submitting: false,
    info: { error: false, msg: null }
  });
};
  • Related