'How to make dynamic state for multiple fields in react?
class Bills extends Component {
constructor(props) {
super(props)
this.state = {
productName: '',
price: 0,
quantity: 0,
noOfProductsField: 0
}
}
handleChange = name => event => {
this.setState({
[name]: event.target.value,
});
};
createFields = () => {
const { classes } = this.props;
let children = []
for (let i = 0; i < this.state.noOfProductsField; i++) {
children.push(
<div>
<Select
className={classes.textField}
value = { this.state[i] }
onChange={this.handleChange('productName')}
displayEmpty
SelectProps={{
MenuProps: {
className: classes.menu,
}
}}>
<MenuItem value="" disabled>
Select Product
</MenuItem>
{this.state.products.map((option, ind) => (
<MenuItem key={ind} value={option.productName}>
{option.productName}
</MenuItem>
))}
</Select>
<TextField className={classes.textField} placeholder='Price' type='number' onChange={this.handleChange('price')} />
<TextField className={classes.textField} placeholder='Quantity' type='number' onChange={this.handleChange('quantity')} />
</div>
)
}
return children
}
}
I Have this function which is creating 3 input fields in for loop
- productName
- price
- quantity
For Example if loop is running 2 times it will create 6 fields like image below:

So now i want to manage state for all 6 fields differently How can i do that ?
Solution 1:[1]
You can add name attribute to each input component and make one handler method which get the name as an argument.
handleInputChange(event) {
const value = event.target.value;
const name = event.target.name;
this.setState({
[name]: value
});
}
You can read more about how to handle multiple inputs on React docs.
Solution 2:[2]
you can create dynamic select field using react js
**Code sample:**
const templates = [
{'id': 1, 'value': 'JavaScript', 'name': 'JavaScript'},
{'id': 2, 'value': 'React', 'name': 'React'},
{'id': 3, 'value': 'Angular', 'name': 'Angular'},
{'id': 4, 'value': 'Node', 'name': 'Node'},
{'id': 5, 'value': 'Vue', 'name': 'Vue'},
]
class Dynamic extends React.Component {
state={
selectedTemplates: ""
}
onChange = (e) => {
console.log(e)
// selected value store into state
this.setState({
selectedTemplates: e.target.value
});
};
render() {
return (
<div>
<h2>Dynamic Select(Options):</h2>
<select className="form-control"
value={this.state.value}
onChange={(e) => this.onChange(e.target.value)}
>
{
templates.map(msgTemplate => {
return (
<option
key={msgTemplate.id}
name={msgTemplate.name}
value={msgTemplate.text}
>
{msgTemplate.name}
</option>
)
})
}
</select>
</div>
)
}
}
React.render(<Dynamic />, document.getElementById('app'));
demo >> codepen
Solution 3:[3]
Simple example for the state variables looks like:
this.state = {
test: 'hello'
}
you can get the state values dynamically by
let field_name = 'test';
let data = this.state[field_name];
you can set the state or replace the state like
let field_name = 'test';
this.setState({[field_name]: 'new'}) // test: 'new'
complex state replace like
let field_names = {key: 'test'}
this.setState({[field_name.key]: 'ok'}) // test: 'ok'
console.log(this.state[field_name.key]) // test: 'ok'
You can also use the Template literals like
this.setState({`${field_name.key}`: 'ok'}) // test: 'ok'
console.log(this.state[`${field_name.key}`]) // test: 'ok'
Superb, you got the solution.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | zb22 |
| Solution 2 | Rizwan |
| Solution 3 |
