handling select options in React Hooks
Asked Answered
S

5

21

I am trying to get the text value from a dropdown select using {useState} in React Hooks. I just get the value (number) rather than the text. I've copied the bits of code below which control the select dropdown. What am I missing here?

const [addrtype, setAddrType] = useState('Home')
    
function handleAddrTypeChange(e) {
  setAddrType(e.target.value);
  console.log(addrtype)
}
  
<select
  defaultValue={addrtype}
  onChange={handleAddrTypeChange}
  className="browser-default custom-select">
    
  <option selected value="1">Home</option>
  <option value="2">Marketing</option>
  <option value="3">Work</option>
  <option value="3">Head Office</option>

</select>
Sclater answered 26/9, 2019 at 10:32 Comment(0)
I
19
import React, { useState, Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';

const App = () => {

  const [addrtype, setAddrtype] = useState(["Work", "Home", "school"])
  const Add = addrtype.map(Add => Add
  )
  const handleAddrTypeChange = (e) => console.log((addrtype[e.target.value]))

  return (
    < select
      onChange={e => handleAddrTypeChange(e)}
      className="browser-default custom-select" >
      {
        Add.map((address, key) => <option value={key}>{address}</option>)
      }
    </select >)


}

render(<App />, document.getElementById('root'));

Working example

https://stackblitz.com/edit/react-select-hook
Inward answered 26/9, 2019 at 12:19 Comment(3)
Thanks but im getting 'key is not defined' on the example.Sclater
stackblitz.com/edit/react-select-hook - please take a re-look hereInward
@AshifZafar but how will we again set state after selecting it is not working for setAddrtypeHaakon
A
5

If you want text then access text instead of value. event.target.text. Check the reference here. http://output.jsbin.com/vumune/4/

Ambush answered 26/9, 2019 at 10:36 Comment(3)
When I change to setAddrType(e.target.text); console.log(addrtype.text) I get undefined and Uncaught TypeError: Cannot read property 'text' of undefinedSclater
checked your example. working now with this. Thanks. function handleAddrTypeChange(e) { var id = e.target.selectedIndex; setAddrType(e.target[id].text); console.log(addrtype) }Sclater
why is the initial selection blank and then any other selections are one behind in the console.log? @AmbushSclater
S
1

Just change the option value

<option selected value="Home">Home</option>
<option value="Marketing">Marketing</option>
<option value="Work">Work</option>
<option value="Head Office">Head Office</option>
Spode answered 9/1, 2020 at 6:45 Comment(1)
OP needs text but not values. I believe he has good reasons to use numbers in value. You suggestion does not answer the problem.Blanco
G
0
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [addrtype, setAddrtype] = useState(['Normal', 'Admin']);
const Add = addrtype.map(Add => Add);

const handleAddrTypeChange = (e) => {
  console.clear();
  console.log((addrtype[e.target.value]));
  setRole(addrtype[e.target.value]);
};

const [role, setRole] = useState('Normal');

const handleSubmit = (event) => {
  event.preventDefault();
  console.log
  (`
    Name: ${name}
    Email: ${email} 
    Role: ${role}           
  `);
};

const UserForm = (
  <form onSubmit={handleSubmit}>
    <label htmlFor='name'>Name</label>
    <input
      value={name}
      placeholder='Name'
      required
      onChange={(event) => setName(event.target.value)}
    ></input>

    <label htmlFor='email'>Email</label>
    <input
      value={email}
      placeholder='Email'
      required
      onChange={(event) => setEmail(event.target.value)}
    ></input>

    <label for='role'>Choose a Role:</label>
    < select
      onChange={e => handleAddrTypeChange(e)}
      className='browser-default custom-select'>
      {
        Add.map((address, key) => <option key={key} value={key}>{address}
        </option>)
      }
    </select>

    <div class='wrapper'>
      <button type='submit' className='button'>Create User</button>
    </div>
  </form>
);

enter image description here

Galloway answered 29/3, 2021 at 13:49 Comment(0)
G
0

The accepted answer is too tricky for me. I made a simpler one, which can seperate textContent and value of the <option>.

JavaScript

const [addrtype, setAddrType] = useState('1') // Default value here
    
function handleAddrTypeChange(e) {
  setAddrType(e.currentTarget.value);
  // Don't log the state here, it will print the old one since component haven't rerender yet
  console.log(addrtype) 
}

// Don't use defaultValue, it is for uncontrolled input
<select
  value={addrtype}
  onChange={handleAddrTypeChange}
  className="browser-default custom-select">
    
  <option value="1">Home</option>
  <option value="2">Marketing</option>
  <option value="3">Work</option>
  <option value="3">Head Office</option>

</select>

TypeScript

const [addrtype, setAddrType] = useState<string>('1')
    
function handleAddrTypeChange(e: React.ChangeEvent<HTMLSelectElement>) {
  setAddrType(e.currentTarget.value);
}

<select
  value={addrtype}
  onChange={handleAddrTypeChange}
  className="browser-default custom-select">
    
  <option value="1">Home</option>
  <option value="2">Marketing</option>
  <option value="3">Work</option>
  <option value="3">Head Office</option>

</select>
Grobe answered 22/2 at 18:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.