I am a beginner at React JS. I would like to learn how to store selected values in useState.
The form containts four different drop downs and I want to store this selected values in useState so that at the end of the multi step form, user can go back to edit the fields before sub.
import React, {useState} from 'react';
import './paperdetails.css';
import IncDecCounter from './IncDecCounter'
import {
Text
} from '#chakra-ui/react';
const PaperDetails = () => {
const [selected, setSelected] = useState();
return (
<div className='paper-details'>
<div className='paper-details_display_flex'>
<div className='left'>
<div className='left-calc_wrapper'>
<div>
<label>Type of Paper</label>
<select>
<option value="essay">Paraphrasing</option>
<option value="Custom Writing">Custom Writing</option>
<option selected value="Dissertation">Dissertation</option>
<option value="Research Paper">Research Paper</option>
<option value="essay">Essay</option>
<option value="Term Paper">Term Paper</option>
<option selected value="Admission Essay">Admission Essay</option>
<option value="Coursework">Coursework</option>
<option value="Book Review">Book Review</option>
<option selected value="Paraphrasing">Essay</option>
<option value="Physics Paper">Physics Paper</option>
</select>
</div>
<div>
<label>Study Level</label>
<select>
<option value="school">Bachelor</option>
<option value="college">College</option>
<option selected value="Bachelor">School</option>
<option value="Masters">Masters</option>
</select>
</div>
</div>
<div className='left_middle'>
<div className='calc-control'>
<label>Number of Pages</label>
<IncDecCounter />
</div>
<div className="select-deadline">
<label>Deadline</label>
<select className='deadline' value={selected} onChange={e=>setSelected(e.target.value)}>
<option value="1 hour">1 hour</option>
<option value="3 hours">3 hours</option>
<option selected value="8 hours">8 hours</option>
<option value="12 hours">12 hours</option>
<option value="24 hours">24 hours</option>
<option value="48 hours">48 hours</option>
<option selected value="3 days">3 days</option>
<option value="5 days">5 days</option>
<option value="7 days">7 days</option>
<option selected value="14 days">14 days</option>
</select>
<span color={'#785aec'} fontSize={'14px'}
fontWeight={'bold'}> Will be ready in: {selected}
</span>
</div>
</div>
<section className="writing-instructions">
<div className="writing_instructions">
<div className="d-flex">
<label className='instructions'>
Writing instructions
<span className='text-orange'> *required</span>
</label>
<input className="input-file" id="my-file" type="file"
accept="application/pdf,application/msword,
application/vnd.openxmlformats-officedocument.wordprocessingml.document"/>
<label tabindex="0" for="my-file" className="input-file-trigger">
<span className='span--underlinel-blue'> Upload writing Instructions</span>
</label>
</div>
<div className='text-area'>
<textarea className='text-area_main'
placeholder='Type your instructions here. Please provide as many details as possible.'></textarea>
</div>
</div>
</section>
</div>
<div className='right'>
<div className='total-row'>
<div className='total-text'>
<h1 className='total-text_h1'>Total:</h1>
<span className='span_price'>$0.00</span>
</div>
</div>
</div>
</div>
</div>
)
}
export default PaperDetails;
How to store multiple values in state
to do this ,you will need to define state for all four select box like this
const [seleccedValue1,setSelectedValue1]=useState(null);
const [seleccedValue2,setSelectedValue2]=useState(null);
const [seleccedValue3,setSelectedValue3]=useState(null);
const [seleccedValue4,setSelectedValue4]=useState(null);
then you will need to handle on change event of each select box like this
<select onChange={(e)=>{setSelectedValue1(e.target.value)}}>
<option value="essay">Paraphrasing</option>
<option value="Custom Writing">Custom Writing</option>
<option selected value="Dissertation">Dissertation</option>
<option value="Research Paper">Research Paper</option>
<option value="essay">Essay</option>
<option value="Term Paper">Term Paper</option>
<option selected value="Admission Essay">Admission Essay</option>
<option value="Coursework">Coursework</option>
<option value="Book Review">Book Review</option>
<option selected value="Paraphrasing">Essay</option>
<option value="Physics Paper">Physics Paper</option>
</select>
you can do the same for other select boxes as well
Please checkout this question:
It was already answered here:
React JSX: selecting "selected" on selected <select> option
Here is how you store value of any input field in useState();
const [selected,setSelected] = useState({});
function handleChange(event){
setSelected({...selected,[event.targe.id]=event.target.value});
}
return(
<select
id={"id_0"}
value={selected["id_0"]}
onChange={(event)=>(handleChange(event))}>
......."your code continue here"
and here is how you handle multiple input fields.
<select id={'id_1'} value={selected['id_1']}
onChange={(event)=>(handleChange(event))}/>
<select id={'id_2'} value={selected['id_2']}
onChange={(event)=>(handleChange(event))}/>
Related
I am using useRef to search for specific flights using a flight booking form having input fields and select with options field. The search works with input fields by adding ref={} property to it. However, I don't know how to apply the same method with select fields. Does anyone have a clue about how it's done?
Here's the full code for the Search component below:
import React, { useState, Fragment, useRef } from "react";
import {Container} from "react-bootstrap";
import axios from "axios";
import {FontAwesomeIcon} from '#fortawesome/react-fontawesome'
import {faPlane} from '#fortawesome/free-solid-svg-icons'
// import { useNavigate } from 'react-router-dom';
const Search = ({ onFlightsChange }) => {
const departureCity = useRef("");
const destinationCity = useRef("");
const departureDate = useRef("");
const arrivalDate = useRef("");
const cabinClass = useRef("");
const numOfPassengers = useRef("");
const [flights, setFlights] = useState([]);
function handleClick() {
console.log("Button clicked");
var body = {};
if (departureCity.current.value !== "") {
body["from"] = departureCity.current.value;
}
if (destinationCity.current.value !== "") {
body["to"] = destinationCity.current.value;
}
if (departureDate.current.value !== "") {
body["departureDate"] = departureDate.current.value;
}
if (arrivalDate.current.value !== "") {
body["arrivalDate"] = arrivalDate.current.value;
}
if (cabinClass.current.value !== "") {
body["eSeatsAvailable"] = cabinClass.current.value;
}
if (numOfPassengers.current.value !== "") {
body["numberOfPassengers"] = numOfPassengers.current.value;
}
axios
.post("/flights/find", body)
.then((res) => {
console.log(res.data);
setFlights(res.data);
onFlightsChange(res.data);
})
.catch((err) => console.log(err));
}
return (
<Fragment>
<Container>
<div id="search-form-card" class="card shadow mb-5 bg-white rounded">
<div id="search-form-card-body" className="card-body">
<p id="search-form-title" class="card-title text-center shadow mb-5 rounded">Find your flight < FontAwesomeIcon icon = {faPlane} color="blue" /></p>
</div>
<div class="row">
<div class="col-sm-6">
<select class="browser-default custom-select mb-4" id="select">
<option id="departure-city" value="" disabled="" selected="">Departure city</option>
<option value="1">Cairo</option>
<option value="2">Berlin</option>
<option value="3">Paris</option>
</select>
</div>
<div class="col-sm-6">
<select class="browser-default custom-select mb-4" id="select">
<option id="destination-city" value="" disabled="" selected="">Departure city</option>
<option value="1">Cairo</option>
<option value="2">Berlin</option>
<option value="3">Paris</option>
</select>
</div>
<div class="row">
<div class="col-sm-6">
<input
placeholder="Departure date"
type="text" id="date-picker-example"
class="form-control datepicker mb-4"
ref={departureDate}
/>
</div>
<div class="col-sm-6">
<input
placeholder="Arrival date"
type="text"
id="date-picker-example"
class="form-control datepicker mb-4"
ref={arrivalDate}
/>
</div>
</div>
<div class="row mt-4">
<div class="col-sm-6"><select class="browser-default custom-select mb-4" id="select">
<option id="departure-time" value="" disabled="" selected="">Departure time</option>
<option value="1">6:00 AM</option>
<option value="2">3:00 PM</option>
<option value="3">6:00 PM</option>
</select>
</div>
<div class="col-sm-6"><select class="browser-default custom-select mb-4" id="select">
<option
id="departure-time"
value="" disabled=""
selected="">Arrival time
</option>
<option value="1">6:00 AM</option>
<option value="2">3:00 PM</option>
<option value="3">6:00 PM</option>
</select>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<select class="browser-default custom-select mb-4" id="select">
<option id="children" value="" disabled="" selected="">Children</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<div class="col-sm-4">
<select class="browser-default custom-select mb-4" id="select">
<option id="children" value="" disabled="" selected="">Adults</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
</div>
<button className="btn btn-primary float-right mt-5" onClick=
{handleClick}>Search</button>
</div>
</div><br/>
</Container>
</Fragment>
);
};
export { Search };
(Modified section):
function handleClick() {
console.log("Button clicked");
var body = {};
let value = null;
if (departureCity.current.value !== "") {
// body["from"] = departureCity.current.value;
value = departureCity.current.value;
}
<select class="browser-default custom-select mb-4" id="select" ref={departureCity}>
<option id="departure-city" value="" disabled="" selected="">Departure city</option>
<option value="1">Cairo</option>
<option value="2">Berlin</option>
<option value="3">Paris</option>
</select>
It's them same as input, there is no difference, you can do it like this:
const selectRef= useRef("");
...
<select name="myName" id="myId" ref={selectRef}>
<option valie="myValue">my text</option>
...
</select>
to read the value related to select, you can do it like what you did with input's ref.
const value = selectRef.current.value;
BTW there are many duplicated id in your code, don't do that, element's id must be unique.
I have a quiz application that you can choose amount of question,difficulty etc.After submitting you will directed to quiz screen.I have a parent component called App and child component called StartScreen. I want to change some states in child component and submit them.After summitting I will see the quiz testing screen.In parent component I have a state called start.When I change start from false to true I will see the quiz screen.My problem is that, when I change start to true in child component it refresh the page.So I cant see quiz screen
Parent component
import './App.css';
import React, { useState, useEffect } from 'react';
import QuestionGrid from './components/QuestionGrid';
import StartScreen from './components/StartScreen';
function App() {
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState([]);
const [amount, setAmount] = useState("10");
const [category, setCategory] = useState("23");
const [difficulty, setDifficulty] = useState('easy');
const [start, setStart] = useState(false);
useEffect(() => {
fetch(
`https://opentdb.com/api.php?amount=${amount}&category=${category}&difficulty=${difficulty}&type=multiple`
)
.then((res) => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result.results);
},
(error) => {
setIsLoaded(true);
setError(error);
}
);
}, [amount,category,difficulty]);
console.log(error);
console.log(isLoaded);
return start === true ? (
<div className="App">
<QuestionGrid isLoaded={isLoaded} items={items} />
</div>
) : (
<div>
<StartScreen amount={(e)=>setAmount(e)} category={(e)=>setCategory(e)} difficulty={(e)=>setDifficulty(e)}/>
</div>
);
}
export default App;
This is my child component
import React, { useState, useEffect } from 'react';
export default function startScreen(props) {
return (
<section className="mt-3">
<header className="text-center">
<h2>Welcome to QUIZ</h2>
</header>
<div className="col-sm-6 m-auto">
<form action="">
<input
onChange={(e)=>(props.amount(e.target.value))}
placeholder="Select amount of questions"
type="number"
name="trivia_amount"
id="trivia_amount"
class="form-control"
min="1"
max="50"
></input>
<select
class="form-select form-select-md "
aria-label=".form-select-lg example"
onChange={(e)=>(props.category(e.target.value))}
>
<option selected>Select the category</option>
<option value="any">Any Category</option>
<option value="9">General Knowledge</option>
<option value="10">Entertainment: Books</option>
<option value="11">Entertainment: Film</option>
<option value="12">Entertainment: Music</option>
<option value="13">Entertainment: Musicals & Theatres</option>
<option value="14">Entertainment: Television</option>
<option value="15">Entertainment: Video Games</option>
<option value="16">Entertainment: Board Games</option>
<option value="17">Science & Nature</option>
<option value="18">Science: Computers</option>
<option value="19">Science: Mathematics</option>
<option value="20">Mythology</option>
<option value="21">Sports</option>
<option value="22">Geography</option>
<option value="23">History</option>
<option value="24">Politics</option>
<option value="25">Art</option>
<option value="26">Celebrities</option>
<option value="27">Animals</option>
<option value="28">Vehicles</option>
<option value="29">Entertainment: Comics</option>
<option value="30">Science: Gadgets</option>
<option value="31">Entertainment: Japanese Anime & Manga</option>
<option value="32">
Entertainment: Cartoon & Animations
</option>{' '}
</select>
<select
class="form-select form-select-md mb-5"
aria-label=".form-select-lg example"
onChange={(e)=>(props.difficulty(e.target.value))}
>
<option selected>Select the difficulty</option>
<option value="any">Any Difficulty</option>
<option value="easy">Easy</option>
<option value="medium">Medium</option>
<option value="hard">Hard</option>
</select>
<button type="submit" value="true" className="btn btn-danger col-sm-4 m-auto d-flex justify-content-center" onClick={(e)=>(alert(e.target.value))}>
Submit
</button>
</form>
</div>
</section>
);
}
You need to stop page from reloading by using preventDefault
import React, { useState, useEffect, useCallback } from 'react';
export default function startScreen(props) {
const handleSubmit = useCallback((event) => {
event.preventDefault()
alert(event.target.value)
}, [])
return (
<section className="mt-3">
<header className="text-center">
<h2>Welcome to QUIZ</h2>
</header>
<div className="col-sm-6 m-auto">
<form action="">
<input
onChange={(e) => (props.amount(e.target.value))}
placeholder="Select amount of questions"
type="number"
name="trivia_amount"
id="trivia_amount"
class="form-control"
min="1"
max="50"
></input>
<select
class="form-select form-select-md "
aria-label=".form-select-lg example"
onChange={(e) => (props.category(e.target.value))}
>
<option selected>Select the category</option>
<option value="any">Any Category</option>
<option value="9">General Knowledge</option>
<option value="10">Entertainment: Books</option>
<option value="11">Entertainment: Film</option>
<option value="12">Entertainment: Music</option>
<option value="13">Entertainment: Musicals & Theatres</option>
<option value="14">Entertainment: Television</option>
<option value="15">Entertainment: Video Games</option>
<option value="16">Entertainment: Board Games</option>
<option value="17">Science & Nature</option>
<option value="18">Science: Computers</option>
<option value="19">Science: Mathematics</option>
<option value="20">Mythology</option>
<option value="21">Sports</option>
<option value="22">Geography</option>
<option value="23">History</option>
<option value="24">Politics</option>
<option value="25">Art</option>
<option value="26">Celebrities</option>
<option value="27">Animals</option>
<option value="28">Vehicles</option>
<option value="29">Entertainment: Comics</option>
<option value="30">Science: Gadgets</option>
<option value="31">Entertainment: Japanese Anime & Manga</option>
<option value="32">
Entertainment: Cartoon & Animations
</option>{' '}
</select>
<select
class="form-select form-select-md mb-5"
aria-label=".form-select-lg example"
onChange={(e) => (props.difficulty(e.target.value))}
>
<option selected>Select the difficulty</option>
<option value="any">Any Difficulty</option>
<option value="easy">Easy</option>
<option value="medium">Medium</option>
<option value="hard">Hard</option>
</select>
<button type="submit" value="true" className="btn btn-danger col-sm-4 m-auto d-flex justify-content-center" onClick={handleSubmit}>
Submit
</button>
</form>
</div>
</section>
);
}
I'm following the official React docs to build a simple form which, however, doesn't work as intended.
const [value, setValue] = useState("banana")
...
<form onSubmit={handleSubmit}>
<label>
Pick your favorite flavor:
<select value={value} onChange={handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
As far as I understood, it has to display "banana" as the initial value, whereas it shows "grapefruit". Why is it so?
Here's the link to the docs: https://reactjs.org/docs/forms.html
In the "Forms" section there's an example from where I took the code. It, however, uses class-based components while I use reactHooks. Might it be the problem?
Many thanks!
It shows the first option because value isn't an attribute of <select>. If you want to select one, you need to add a selected attribute to one of the options.
For example:
<label>
Pick your favorite flavor:
<select onChange={handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option selected={true} value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
This is generally written as
const options = ["grapefruit", "lime", "coconut", "mango"];
const selectedValue = "lime";
<label>
Pick your favorite flavor:
<select onChange={handleChange}>
{options.map(o => (<option value={o} selected={o == selectedValue}>{o}</option>)}
</select>
</label>
<input type="submit" value="Submit" />
It is because banana is not in options. If option's value is not present then it will by default pick the first one(Default behaviour). DEMO
import "./styles.css";
import { useState } from "react";
export default function App() {
const [value, setValue] = useState("mango");
const handleChange = (e) => {
setValue(() => {
return e.target.value;
});
};
return (
<div className="App">
<select value={value} onChange={handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</div>
);
}
Can I use multiple selection with React.createref()? It returns undefined.
<div>
<label>
Pilih Skill :{" "}
<select multiple ref={this.inputSkill}>
<option value="Front-end" key="1">Front-end</option>
<option value="Back-end" key="2">Back-end</option>
<option value="Dev-Ops" key="13">Dev-Ops</option>
<option value="Full Stack" key="41">Full Stack</option>
</select>
</label>
</div>
Is anyone able to explain me why this code is not working?
<div className="row">
<div className="input-field col s12">
<select
onChange={props.handleSelected}
id="realEstateBroker"
defaultValue={'Default'}
>
<option value="Default" disabled>
Brak
</option>
{
realEastateBroker &&
realEastateBroker.map((broker, i) => (
<option key={i} value={broker.firstName}>
{broker.firstName}
</option>
))
}
</select>
<label>Opiekun oferty</label>
</div>
</div>
Options from the map func are not generated on the page. On the chrome console I can see them under select but not in ul list (if I hardcode options, there are working). Working example:
<div className="row">
<div className="input-field col s12">
<select
multiple
onChange={props.handleSelectedMultiple}
id="balcony"
defaultValue={[]}
>
<option value="Default" disabled>
Brak
</option>
<option value="Balkon">Balkon</option>
<option value="Taras">Taras</option>
<option value="Ogród">Ogród</option>
<option value="Loggia">Loggia</option>
<option value="Taras na dachu">Taras na dachu</option>
</select>
<label>Balkon</label>
</div>
</div>
realEstateBroker is array of objects.
<div className="row">
<div className="input-field col s12">
<select
onChange={props.handleSelected}
id="realEstateBroker"
defaultValue={'Default'}
>
<option value="Default" disabled>
Brak
</option>
{
realEastateBroker &&
realEastateBroker.map((broker, i) => {
return(<option key={i} value={broker.firstName}>
{broker.firstName}
</option>
)
})
}
</select>
<label>Opiekun oferty</label>
</div>
</div>
From map you need to return the values to be rendered on UI. Hope this helps!