In a React project, I'am able to pass data from submit button to common function but, I want to pass data from radio button to common function. See for reference below
/* The function where the query is extracted from another function */
/* Common Function -> getData */
const getData = async () => {
/* I get query value from onSubmit and not from handleChange */
console.log('QUERY', query)
if (query !== "") {
const result = await Axios.get(url);
console.log(result)
if (!result.data.more) {
return toast.error('No such food', {
autoClose: 2000
}, setQuery(""))
}
setRecipes(result.data.hits);
setQuery("");
} else {
toast.error('Please Fill the form', {
autoClose: 2000
})
}
};
/* I get value fom this function */
const onSubmit = e => {
e.preventDefault();
getData();
};
const onChange = e =>
{
setQuery(e.target.value);
}
/* I want value from this function to pass to getData() */
const handleChange = e => {
console.log('VALUE', e.target.value)
setQuery(e.target.value);
getData(e)
}
{/* Search Button */}
<form onSubmit={onSubmit} className="search-form">
<input
type="text"
name="query"
onChange={onChange}
value={query}
autoComplete="off"
placeholder="Search Food"
/>
<input type="submit" value="Search" />
<br/>
</form>
{/* Radio Button */}
<ButtonGroup toggle style={{width:'100%'}}>
{radios.map((radio, idx) => (
<ToggleButton
key={idx}
type="radio"
active="true"
variant="light"
name="radio"
value={radio.value}
checked={radioValue === radio.value}
onChange={(e) => {
handleChange(e);
setRadioValue(e.currentTarget.value);
}}
size="lg"
>
{radio.name}
</ToggleButton>
))}
</ButtonGroup>
Thus, I'am unable to get query value from handleChange for Radio Button. No value is shown for handleChange, whereas with onSubmit I do get query value. What could be the better solution to tackle this problem?
I would use state for this. It can be used with a class or functions.
Something like this:
class MyClass extends React.Component {
state = { query: '', recipes: null }
url:string;
render() { }
handleChange = (e) => {
console.log('VALUE', e.target.value);
this.setQuery(e.target.value);
this.getData(e)
}
setQuery = (query) => this.setState({ ...this.state, query });
getData = async (e) => {
const { query } = this.state;
if (query !== "") {
const result = await Axios.get(this.url);
/** same logic is here */
this.setState({ ...this.state, recipes: result.data.hits })
}
}
}
Main benefit of this is the automatic rendering of the element, whenever the state changes. So you will always see actual data on the View.
If you are using React 16.8 and prefer to use functions, you might use hooks
With hooks it will be something like this:
import React, { useState } from 'react';
export default () => {
const [query, setQuery] = useState('');
const [recipes, setRecipes] = useState('');
const setMyQuery = (v: any) => {
console.log(v);
setQuery(v)
}
const handleChange = (e: any) => {
console.log('VALUE', e.target.value);
setMyQuery(e.target.value);
getData(e)
}
const getData = async (_: any) => {
if (query !== "") {
const result = await Promise.resolve('result')
/** same logic is here */
setRecipes(result)
}
}
return (<div>
{recipes}
{query}
<input type="text" onChange={handleChange} />
</div>)
}
You can't rely on the same event target for both these scenarios eg for <input name="query"...
it's fine to use target
because we know we are explicitly interacting with that element.
On the ToggleButton
scenario, the event isn't initiated by the underlying input
field therefore target
& currentTarget
will differ. To be consistent, you can either use e.currentTarget.value
for both scenarios or you can use e.currentTarget
for the Radio button and e.target
for the query input.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.