handling select options in React Hooks - reactjs

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>

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

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

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>

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 >

Related

throw new Error('Maximum update depth exceeded. This can happen when a component ' + 'repeatedly calls setState

i am new to React and i want to handle form submission. I have three components AddTicket, Contacts and Selections. Contacts and Selections are child components and the logic is to send data using useState hook from child components to parent component but it throws the above error.
That happens when update state for selections or contacts inside AddTicket component.
//parent component AddTicket
import Selections from "./Selections";
import Contact from "./Contact";
import { useState } from "react";
function AddTicket() {
const [selections, setSelections] = useState({});
const [description, setDescription] = useState("");
const [contacts, setContacts] = useState({
name: "",
email: "",
phone: ""
});
const submitHandler = (event) => {
event.priventDefault();
const formValues = { ...selections, descr: description, ...contacts };
console.log(`${formValues}`);
};
const selecitonsHandler = (selections) => {
//console.log(
//`${selections.selectedAsset} ${selections.selectedCategory} ${selections.selectedPriority}`
//);
setSelections({
asset: selections.selectedAsset,
category: selections.selectedCategory,
priority: selections.selectedPriority,
});
};
const descriptionHandler = (event) => {
console.log(event.target.value);
setDescription(event.target.value);
};
const altValuesHandler = (altValues) => {
//console.log(`${altValues.name} ${altValues.email} ${altValues.phone}`);
setContacts({
name: altValues.name,
email: altValues.email,
phone: altValues.phone,
});
};
return (
<div>
<div>
<h4>Add Ticket</h4>
</div>
<div>
<form onSubmit={submitHandler}>
<div>
<Selections onChange={selecitonsHandler} />
</div>
<div>
<textarea
defaultValue="Description"
onChange={descriptionHandler}
></textarea>
</div>
<div>
<Contact onChange={altValuesHandler} />
</div>
<div>
<input type="submit" value="Create" />
</div>
</form>
</div>
</div>
);
}
export default AddTicket;
//child component Contacts
import { useState } from "react";
function Contact({ onChange }) {
const [altName, setAltName] = useState("");
const [altEmail, setAltEmail] = useState("");
const [altPhone, setAltPhone] = useState("");
const altNameHandler = (event) => {
setAltName(event.target.value);
};
const altEmailHandler = (event) => {
setAltEmail(event.target.value);
};
const altPhoneHandler = (event) => {
setAltPhone(event.target.value);
};
const altValues = {
name: altName,
email: altEmail,
phone: altPhone,
};
onChange(altValues);
return (
<div>
<label>Contact</label>
<div>
<input
type="text"
defaultValue="Alternative name"
onChange={altNameHandler}
/>
</div>
<div>
<input
type="text"
defaultValue="Alternative email"
onChange={altEmailHandler}
/>
<input
type="text"
defaultValue="Alternative phone"
onChange={altPhoneHandler}
/>
</div>
</div>
);
}
export default Contact;
//child component Selections
import { useState } from "react";
function Selections({ onChange }) {
const [asset, setAsset] = useState("");
const [category, setCategory] = useState("");
const [priority, setPriority] = useState("");
const assetHandler = (event) => {
setAsset(event.target.value);
};
const categoryHandler = (event) => {
setCategory(event.target.value);
};
const priorityHandler = (event) => {
setPriority(event.target.value);
};
const selections = {
selectedAsset: asset,
selectedCategory: category,
selectedPriority: priority,
};
onChange(selections);
return (
<div>
<div>
<select onChange={assetHandler}>
<option selected disabled hidden>
Asset
</option>
<option value="Selection 1">Selection 1</option>
<option value="Selection 2">Selection 2</option>
</select>
</div>
<div>
<select onChange={categoryHandler}>
<option selected disabled hidden>
Category
</option>
<option value="Selection 1">Selection 1</option>
<option value="Selection 2">Selection 2</option>
</select>
</div>
<div>
<select onChange={priorityHandler}>
<option selected disabled hidden>
Priority
</option>
<option value="High">High</option>
<option value="Medium">Medium</option>
<option value="Low">Low</option>
</select>
</div>
</div>
);
}
export default Selections;

ReactJS select first option doesn't work properly

I have a react app with edit logic with select tag and options for continents and countries. In the continents it seems everything is alright but in countries I can't set a first option. First I must to select another country and then first option is available for set.
This is my code:
import React, { useState, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import styles from './editContact.module.css';
import { urls, methods } from '../constants';
import requester from '../services/requester';
import notificationsReceiver from '../services/notificationReceiver';
const EditContact = () => {
const id = window.location.pathname.slice(14);
const navigate = useNavigate();
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [description, setDescription] = useState('');
const [categories, setCategories] = useState('');
const [areas, setAreas] = useState('');
const [event, setEvent] = useState('');
const [continentId, setContinent] = useState('');
const [countryId, setCountry] = useState('');
const [continents, setContinents] = useState([]);
const [countries, setCountries] = useState([]);
const getContact = useCallback(async () => {
const request = await requester(urls.contacts + '/' + id, methods.get);
const response = await request.json();
setName(response.name);
setEmail(response.email);
setAreas(response.areas);
setCategories(response.categories);
setDescription(response.description);
setEvent(response.event);
setPhone(response.phoneNumber);
setContinent(response.continentId);
setCountry(response.countryId);
}, [id]);
const sendToHome = () => {
navigate(urls.mainPage);
};
const editContact = async (e) => {
e.preventDefault();
await requester(urls.contacts + '/' + id, methods.put, {
name,
email,
phone,
description,
areas,
event,
categories,
continentId,
countryId
}
)
.then(() => {
navigate(urls.mainPage);
notificationsReceiver('Contact is edited successfully!');
})
.catch((e) => {
alert(e.message);
})
};
const getContinents = async () => {
const request = await requester(urls.getContinents, methods.get);
const response = await request.json();
setContinents(response);
};
const getCountries = async () => {
const request = await requester(urls.getCountries, methods.get);
const response = await request.json();
setCountries(response);
};
useEffect(() => {
getContact();
getContinents();
getCountries();
}, [getContact]);
return (
<form className={styles['edit-form']} onSubmit={editContact}>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Name</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setName(e.target.value)} value={name} />
</div>
<label htmlFor="exampleFormControlInput1">Continent</label>
<select className="form-control" id="exampleFormControlSelect1" title="continent" name="continent" onChange={e => setContinent(e.target.value)} value={continentId}>
{continents.map(continent =>
<option key={continent.continentId} value={continent.continentId}>{continent.continentName}</option>
)}
</select>
<label htmlFor="exampleFormControlInput1">Countries</label>
<select className="form-control" id="exampleFormControlSelect1" title="country" name="country" onChange={e => setCountry(e.target.value)} value={countryId}>
{countries.filter(x => x.placeIsContainedInId === continentId).map(country =>
<option key={country.countryId} value={country.countryId}>{country.countryName}</option>
)}
</select>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">eMail</label>
<input type="email" className="form-control" id="exampleFormControlInput1" onChange={e => setEmail(e.target.value)} value={email} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Phone</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setPhone(e.target.value)} value={phone} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Description</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setDescription(e.target.value)} value={description} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Categories</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setCategories(e.target.value)} value={categories} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Areas</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setAreas(e.target.value)} value={areas} />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlInput1">Event</label>
<input type="text" className="form-control" id="exampleFormControlInput1" onChange={e => setEvent(e.target.value)} value={event} />
</div>
<button type='submit' className='btn btn-success mt-5' style={{ marginRight: 5 + 'px' }} name='edit'>Submit</button>
<button className='btn btn-secondary mt-5' onClick={sendToHome}>Cancel</button>
</form>
);
};
export default EditContact;
If someone knows how to resolve this problem, I'll be grateful.

Can't type in textarea when displayed

import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState("")
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
console.log(name)
}
return (
<form onSubmit={handleSumbit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={handleSumbit}></textarea>
<input type="submit" />
</form>
)
}
When the text box is displayed I cannot type in it.
What am I doing wrong...?
import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState('')
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
console.log(name)
}
return (
<form onSubmit={handleSumbit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={(e) => setTextArea(e.target.value)}></textarea>
<input type="submit" />
</form>
)
}
The textarea is a controlled input - if you are going to tie the value of the <textarea> to the textArea state variable, you need to update that state variable whenever the user changes the input.
Shouldn't the onChange={handleSumbit} of the textarea be
onChange={(e) => setTextArea(e.target.value)}
import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState("")
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
console.log(name)
}
return (
<form onSubmit={handleSumbit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setTextArea(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={handleSumbit}></textarea>
<input type="submit" />
</form>
)
}
Firstly
You implicitly set the value of your text area using the textArea variable which has an initial state of "" (an empty string).
React automatically refreshes the real DOM from the virtual DOM after every change in state. But the value of your textArea variable doesn't change with this event, so you have to update the state when a value is entered like this:
onChange={(e) => setTextArea(e.target.value)}
After reading your code, I guessed what you wanted to achieve is to prevent the submit button from submitting the form by default and instead logs the name on the console.
I believe this is the code you wanted to achieve:
import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState('')
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
console.log(name)
}
return (
<form onSubmit={handleSumbit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={(e) => setTextArea(e.target.value)}></textarea>
<input type="submit" />
</form>
)
You can't type here the event not written by you properly, so, you state textarea not updated yet. just needed to change one as a similar name textbox. just replace
<textarea value={textArea} onChange={handleSumbit}></textarea>
to
<textarea value={textArea} onChange={(e) => setTextArea(e.target.value)}></textarea>
Full code here edited,
import React, { useState } from 'react'
const FormBox = () => {
const [name, setName] = useState('')
const [textArea, setTextArea] = useState('')
const handleSumbit = (e) =>{
e.preventDefault();
// console here form data
}
return (
<form onSubmit={(e)=>handleSumbit(e)}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<textarea value={textArea} onChange={(e) => setTextArea(e.target.value)}></textarea>
<input type="submit" value="Submit now!" />
</form>
)
I Hope, work fine using this code
Thanks

How do I reset a dropdown selector to its default value after a state reset? When I use the event handler below it doesn't revert

------------------form jsx-----------------------------
<label htmlFor = 'size'>
What size pizza would you like?
<br/>
<select name = 'size' id = 'sizeinput' onChange = {inputChange}>
<option value={null}disabled selected>Select</option>
<option value='Sm'>Sm</option>
<option value='Lg'>Lg</option>
<option value='XL'>XL</option>
</select>
</label>
------------------------form submit---------------------------
const formSubmit = e => {
e.preventDefault();
axios
.post("https://reqres.in/api/users", formState)
.then(res => {
setPost(res.data);
console.log("success", post);
setFormState({
size: ""
});
})
.catch(err => console.log(err.response));
};
The default value is set by using the value prop for select, see the docs here.
Therefore, you should bind the formState.size with the value prop. That way you can initialize it with null so that it's selected by default on mount and then reset it back to null when you're done.
<select value={formState.size} name='size' id='sizeinput' onChange={inputChange}>
<option value={null} disabled>Select</option>
<option value='Sm'>Sm</option>
<option value='Lg'>Lg</option>
<option value='XL'>XL</option>
</select>
You also have to give value attribute in select input.
import React, { useState } from 'react';
import axios from 'axios';
const Dashboard = () => {
const [formState, setFormState] = useState({ size: '' });
const [post, setPost] = useState({});
const inputChange = (e) => {
setFormState({
size: e.target.value,
});
};
const onFormSubmit = (e) => {
e.preventDefault();
axios
.post('https://reqres.in/api/users', formState)
.then((res) => {
setPost(res.data);
setFormState({ size: '' });
})
.catch((err) => console.log(err.response));
};
console.log(post);
return (
<form onSubmit={onFormSubmit}>
<label htmlFor="size">
What size pizza would you like?
<br />
<select value={formState.size} name="size" id="sizeinput" onChange={inputChange}>
<option value="" disabled selected>Select</option>
<option value="Sm">Sm</option>
<option value="Lg">Lg</option>
<option value="XL">XL</option>
</select>
</label>
<button type="submit">Submit</button>
</form>
);
};
export default Dashboard;
this is where you made the mistake
<select name = 'size' id = 'sizeinput' onChange = {inputChange}>
To
<select value={formState.size} name="size" id="sizeinput" onChange={inputChange}>

When i click the menu in drop down, How can i be able to pass value and hit second api?

export default App;
How do i pass value to second api
import React, { useState } from "react";
import axios from "axios";
let App = () => {
let [value, setValue] = useState('');
let [locations, setLocations] = useState([]);
let handleSubmit = async () => {
if (value === "") return;
let response = await axios.get(`https://api2-4ofagodxfq-uc.a.run.app/locality?stateName=KARNATAKA&districtName=BANGALORE&pinCode=${value}`);
if (response.status === 200) setLocations(response.data);
}
let handleChange = async () => {
if (value === "") return;
let response1 = await axios.get(`https://api2-4ofagodxfq-uc.a.run.app/branch?stateName=KARNATAKA&districtName=BANGALORE&pinCode=560001&officeName=${value}`);
if (response1.status === 200) setLocations(response1.data);
}
return <div>
STATE:<select value="KARNATAKA">
<option value="KARNATAKA">KARNATAKA</option>
</select>
<br />
CITY:<select value="BANGALORE">
<option value="BANGALORE">BANGALORE</option>
</select>
<br />
PINCODE:<input type="text" onChange={e => setValue(e.target.value)} onKeyPress={(handleSubmit)} />
<br />
<select onChange={e => setValue(e.target.value1)} >
{locations.map((location, index) => {
return <option key={index}>{location}</option>
})}
</select>
<input type="submit" onClick={(handleChange)}></input>
{locations.map((location, index) => {
return <p key={index}>{location}</p>
})}
</div>
}
export default App;
That too in the same page
you need to wrap all form fields in <form /> call handleSubmit() on submit
something like this
<form submit={() => handleSubmit()}>
STATE:<select value="KARNATAKA">
<option value="KARNATAKA">KARNATAKA</option>
</select>
<br />
CITY:<select value="BANGALORE">
<option value="BANGALORE">BANGALORE</option>
</select>
<br />
PINCODE:<input type="text" onChange={e => setValue(e.target.value)} onKeyPress={(handleSubmit)} />
<br />
<select onChange={e => setValue(e.target.value1)} >
{locations.map((location, index) => {
return <option key={index}>{location}</option>
})}
</select>
<input type="submit" onClick={(handleChange)}></input>
{locations.map((location, index) => {
return <p key={index}>{location}</p>
})}
</>

Resources