Good afternoon everyone.
I have a dropdown with two input fields inside. Name and Price.
I would like to display the name and price after I click Set button that it appears in the same dropdown but on top of input fields.
Here is how it looks in my app currently, I enter name and price by myself.
As you can see in a first field there is a name and in the second there is a number and I wan't to store it under Price Alert History after clicking Set button.
Here is how I wish it will look. It's just an example which was made in photoshop. The main thing that I want to see name and price on top of input field.
CODE HERE
import React from "react";
import { Button} from "react-bootstrap";
const symbols = [
"ADABTC",
"AIONBTC",
"ALGOBTC",
"ARDRBTC",
"KAVABTC",
"ETHBTC",
"ETCBTC"
];
function PriceTriggerField() {
const [searchTerm, setSearchTerm] = React.useState("");
const [searchSymbol, setSearchSymbol] = React.useState([]);
const handleChangeTerm = event => {
setSearchTerm(event.target.value);
};
const handleChangeSymbol = event => {
setSearchSymbol(event.target.value);
};
React.useEffect(() => {
const results = symbols.filter(symbols =>
symbols.toUpperCase().includes(searchTerm)
);
setSearchSymbol(results);
}, [searchTerm]);
return (
<div className="App">
<h6>Price Alert History</h6>
<input
type="text"
placeholder="Symbol"
value={searchTerm}
onChange={handleChangeTerm}
/>
<input
type="number"
placeholder="Price"
/>
{
searchTerm.length > 0 && searchSymbol.map(item => <li onClick={(() => setSearchTerm(item) )}>{item}</li>)
}
<Button variant="secondary">Set</Button>
</div>
);
}
export default PriceTriggerField;
this is just a simple example with only one variable, but of course, you can do that for as many variables as you wish.
import React, { useState } from "react";
export default function App() {
const [name, setName] = useState(null);
let tmpName;
const onChange = e => {
tmpName = e.target.value;
}
return (
<div className="App">
<input onChange={onChange} />
<button onClick={() => setName(tmpName)}>set</button>
name: {name}
</div>
);
}
Related
Why the input only taking inputs from second input only?
import React, { useState } from "react";
import Item from "./Components/Item";
import "./ToDo.css";
function ToDo() {
let toDoIs = document.getElementById("toDoInput");
const [ToDo, setToDoIs] = useState("d");
const [ToDoArray, setToDoArray] = useState([]);
return (
<div>
<h1>ToDo</h1>
<input
id="toDoInput"
onChange={() => {
setToDoIs(toDoIs.value);
}}
type="text"
/>
<button
onClick={() => {
setToDoArray([...ToDoArray, { text: ToDo }]);
toDoIs.value = "";
}}
>
Add
</button>
<Item push={ToDoArray} />
</div>
);
}
export default ToDo;
Why the second input only works, which means whenever I use submit the value from second input only stored and displayed. I don't know why this happens.
There's a few problems here...
Don't use DOM methods in React. Use state to drive the way your component renders
Your text input should be a controlled component
When updating state based on the current value, make sure you use functional updates
import { useState } from "react";
import Item from "./Components/Item";
import "./ToDo.css";
function ToDo() {
// naming conventions for state typically use camel-case, not Pascal
const [toDo, setToDo] = useState("d");
const [toDoArray, setToDoArray] = useState([]);
const handleClick = () => {
// use functional update
setToDoArray((prev) => [...prev, { text: toDo }]);
// clear the `toDo` state via its setter
setToDo("");
};
return (
<div>
<h1>ToDo</h1>
{/* this is a controlled component */}
<input value={toDo} onChange={(e) => setToDo(e.target.value)} />
<button type="button" onClick={handleClick}>
Add
</button>
<Item push={toDoArray} />
</div>
);
}
export default ToDo;
I am trying to make a simple react app that displays radio input for each 'hero' from a list of heroes and if the user checks, the hero's name will be displayed as the favorite hero. But the problem is on my local machine to check a hero I need to double click that radio input. How can I check a hero with a single click?
Code of the app.js file is given below:
import React, { useState } from "react";
import "./App.css";
function App() {
const [heros, setHeros] = useState([
"Superman",
"Batman",
"Antman",
"Robocop",
]);
const [selected, setSelected] = useState(null);
const handleChange = (e) => {
e.preventDefault();
setSelected(e.target.value);
console.log(e.target.checked);
};
return (
<div>
<h1>Select Your Favorite Hero</h1>
<form onChange={handleChange}>
{heros.map((hero, index) => (
<div key={index}>
<input
type="radio"
name="hero"
id={hero}
value={hero}
/>
<label htmlFor="{hero}">{hero}</label>
<br />
</div>
))}
</form>
<div>
<p>Your super hero is: {selected}</p>
</div>
</div>
);
}
export default App;
Remove e.preventDefault() inside handleChange function. Function will be like this one.
const handleChange = (e) => {
setSelected(e.target.value);
console.log(e.target.checked);
};
First, select the button with #btn id, output element with the #output id, and all the radio buttons with the name heros
const btn = document.querySelector('#btn');
const output = document.querySelector('#output');
const radioButtons = document.querySelectorAll('input[name="heros"]');
I have two input fields for an exchange interface. The goal is to update the other according to input (based on exchange rate). User can input in either one.
The problem: if users input 5 and get 500 in the other, then they remove two 0 from 500, it won't be able to get the state update and return 0.05 in the other.
To make it easier to visualize, i have it in codesandbox. Below is the code.
import "./styles.css";
import React from "react";
export default function App() {
const rate = 100;
const [token, setToken] = React.useState();
const [eth, setEth] = React.useState();
console.log("token", token);
console.log("eth", eth);
return (
<div className="App">
<h1>1 eth = 100 token</h1>
<h2>goal: change one input, the other updates automatically</h2>
<input
placeholder="eth"
value={eth}
onChange={(e) => {
let eth_input = e.target.value;
console.log(eth_input);
setToken(eth_input * rate);
}}
/>
<input
placeholder="token"
value={token}
onChange={(e) => {
let token_input = e.target.value;
console.log(token_input);
setEth(token_input / rate);
}}
/>
</div>
);
}
The problem with your code is that your two inputs are both, at least to start with, uncontrolled inputs. And when I run your original codesandbox, there is a console message warning about this, when you edit either of the fields.
This comes about because although your inputs were taking their value from state, their change handlers were not updating that same state with the input value. You were updating the state of the other input, but not those themselves.
Adding the two highlighted lines below, one in each event handler, fixes this, and as far as I can tell makes things function as you intended:
import "./styles.css";
import React from "react";
export default function App() {
const rate = 100;
const [token, setToken] = React.useState();
const [eth, setEth] = React.useState();
console.log("token", token);
console.log("eth", eth);
return (
<div className="App">
<h1>1 eth = 100 token</h1>
<h2>goal: change one input, the other updates automatically</h2>
<input
placeholder="eth"
value={eth}
onChange={(e) => {
let eth_input = e.target.value;
console.log(eth_input);
setEth(eth_input); // <-- add this
setToken(eth_input * rate);
}}
/>
<input
placeholder="token"
value={token}
onChange={(e) => {
let token_input = e.target.value;
console.log(token_input);
setToken(token_input); // <-- and this
setEth(token_input / rate);
}}
/>
</div>
):
}
<input
placeholder="eth"
value={eth}
onChange={(e) => {
let eth_input = e.target.value;
console.log(eth_input);
setEth(eth_input)
setToken(eth_input * rate);
}}
/>
<input
placeholder="token"
value={token}
onChange={(e) => {
let token_input = e.target.value;
console.log(token_input);
setToken(token_input)
setEth(token_input / rate);
}}
/>
I need to display the cascading dropdown for country,state,city from database.If I click the country,the related state only display. And next Click the state the related city only display.
I have compiled some examples found to give a working example:
You can experiment or Try here:
import React, { useState, useEffect } from "react";
import Select from "react-select";
import data from "./data.json";
function DependentSelect() {
const [country, setCountry] = useState(null);
const [lang, setLang] = useState(null);
const [langList, setLangList] = useState([]);
const [link, setLink] = useState("");
// handle change event of the country dropdown
const handleCountryChange = (obj) => {
setCountry(obj);
setLangList(obj.languages);
setLang(null);
};
// handle change event of the language dropdown
const handleLanguageChange = (obj) => {
setLang(obj);
};
// generate the link when both dropdowns are selected
useEffect(() => {
if (country && lang) {
setLink(
`https://www.${country.url}/search?q=Clue+Mediator&gl=${country.country_code}&hl=${lang.code}`
);
}
}, [country, lang]);
return (
<div className="App">
<h3>Dependant dropdown in React - </h3>
<div style={{ width: 400, marginBottom: 20 }}>
<b>Country</b>
<Select
placeholder="Select Country"
value={country}
options={data}
onChange={handleCountryChange}
getOptionLabel={(x) => x.region}
getOptionValue={(x) => x.country_code}
/>
<br />
<b>Language</b>
<Select
placeholder="Select Language"
value={lang}
options={langList}
onChange={handleLanguageChange}
getOptionLabel={(x) => x.name}
getOptionValue={(x) => x.code}
/>
</div>
<span>
<b>Link:</b> {country && lang ? link : "-"}
</span>
</div>
);
}
export default DependentSelect;
I have an exercise where I have to make an input and a button. When I click the button, there has to be created a div/span below, which prints the text which is in input. If I change the text in input, it has to be refreshed in that div/span only when I click the button again. I tried to do it with makeDiv function, but it doesn't do anything. I made console.log(event.target.value) and it handles the text which is in input, but nothing happens then.
My code:
import {useState} from "react"
function About() {
const [initialValue,setInitialValue] = useState('')
const handleValueChange = (event) => {
console.log(event.target.value)
setInitialValue(event.target.value)
}
const makeDiv = () => {
return (<div>Value: {initialValue}</div>)
}
return(
<div>
<button onClick={makeDiv}>click me</button>
<div><input type="text" onChange={handleValueChange} /></div>
</div>
)
}
export default About
edit:
What if I wanted to make an exercise very similar to that, but now, I have to add <li>text in input</li> to <ul> each time I click the button. So when I click the button, I add one li to the list, I tried like this, but it doesn't compile:
import {useState} from "react"
function About() {
const [initialValueLastExercise, setInitialValueLastExercise] = useState([])
const [ValueLE, setValueLE] = useState([])
const handleValueChangeLE = (event) => {
console.log(event.target.value)
setInitialValueLastExercise([...initialValueLastExercise, event.target.value])
}
const showListWithText = () => {
setShouldDisplayText(true)
setValueLE(initialValueLastExercise)
}
return(
<div>
<button onClick={showListWithText}>click me to refresh the list</button>
<div><input type="text" onChange={handleValueChangeLE} /></div>
{shouldDisplayText && <div><ul>
{
for (let i =0; i<initialValueLastExercise.length; i++) {
<li>{initialValueLastExercise[i]}</li>
}
}</div></ul>}
</div>
)
}
export default About
This will refresh the value of the div on button click only as you have mentioned in the question.
import {useState} from "react"
function App() {
const [initialValue,setInitialValue] = useState('')
const [displayText, setDisplayText] = useState(false)
const [Value,setValue] = useState('')
const handleValueChange = (event) => {
setInitialValue(event.target.value)
}
const showText = () => {setDisplayText(true)
setValue(initialValue)};
return(
<div>
<button onClick={showText}>click me</button>
<div><input type="text" onChange={handleValueChange} /></div>
{displayText && <div>Value: {Value}</div>}
</div>
)
}
export default App
Solution for the Edited Question.
import {useState} from "react"
function App() {
const [initialValue,setInitialValue] = useState('')
const [displayText, setDisplayText] = useState(false)
const [Value,setValue] = useState([])
const handleValueChange = (event) => {
setInitialValue(event.target.value)
}
const showText = () => {setDisplayText(true)
setValue([...Value,initialValue])};
return(
<div>
<button onClick={showText}>click me</button>
<div><input type="text" onChange={handleValueChange} /></div>
<ul>{displayText && Value.length > 0 &&
Value.map((i) => {
return <li>Value: {i}</li>
})}</ul>
</div>
)
}
export default App
One way to do it is to create another state variable which indicates whether the div you're trying to make should be displayed and then render it conditionally. Something like
import {useState} from "react"
function About() {
const [initialValue,setInitialValue] = useState('')
const [shouldDisplayText, setShouldDisplayText] = useState(false)
const handleValueChange = (event) => {
console.log(event.target.value)
setInitialValue(event.target.value)
}
const showDivWithText = () => setShouldDisplayText(true);
return(
<div>
<button onClick={showDivWithText}>click me</button>
<div><input type="text" onChange={handleValueChange} /></div>
{shouldDisplayText && <div>Value: {initialValue}</div>}
</div>
)
}
export default About
Your approach is fundamentally wrong.
You should:
Store all the data about the component in the state
Render the output based on the state
So:
You need two state variables:
currentInputValue (because you need to store the value to display and edit in input)
selectedValue (because you need to store the value to be displayed in the div)
When onChange fires, update currentInputValue with the value of the input.
When onClick fires, update selectedValue with the current value of currentInputValue
When you return your data, include something like:
{selectedValue && <div>{selectedValue}</div>}
… to output a div containing the selected value only if there is a truthy value (the default empty string isn't truthy so the div won't be output then)
1st possibility - close to your code source
Don't forget to bind initialValue to the input and to add makeDiv content to the JSX :
return (
<div>
<button onClick={makeDiv}>click me</button>
<input type="text" onChange={handleValueChange} value={initialValue} />
{makeDiv}
</div>
)
2nd possibility - with another approach
return (
<div>
<button onClick={makeDiv}>click me</button>
<input type="text" onChange={handleValueChange} value={initialValue} />
{initialValue && <div>{initialValue}</div>}
</div>
)