Reputation: 29
I'm trying to create a generalized handleChange()
function for all my input fields. I have over 30 input fields, so there is not really an option to have one handleChange method for each input, as this would create tons of boilerplate code. In the example below I have tried to create a function that will handle any input.
For my project, I'm using Ant design, which does not seem to support the name attribute inside their form elements (e.g. InputNumber/Input, etc.)
Example of an InputNumber field:
<InputNumber name='myNumber' min={1} max={100000} placeholder='Enter number' value={this.state.myNumber} onChange={handleChange}/>
This is my attempt at writing a generalized onChange method. But it passes this error: Cannot read property 'name' of undefined
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
});
This method would allow me to reach any selected input element and update that specific one. However, this does work due to the lack of a name attribute.
As suggested below, this approach works, but still leaves me without a generalized solution - a way to handle any input and map to the correct state value.
state = {
myNumber: 0,
myNumber2: 0,
myNumber3: 0
};
handleChange = e => {
this.setState({
myNumber: e
});
};
In the example below the handleChange
function will only update myNumber
, not myNumber2
and myNumber3
.
<InputNumber name='myNumber' min={1} max={100000} placeholder='Enter number' value={this.state.myNumber} onChange={handleChange}/>
<InputNumber name='myNumber2' min={1} max={100000} placeholder='Enter number' value={this.state.myNumber2} onChange={handleChange}/>
<InputNumber name='myNumber3' min={1} max={100000} placeholder='Enter number' value={this.state.myNumber3} onChange={handleChange}/>
Any suggestions to a workaround?
Upvotes: 1
Views: 262
Reputation: 53964
According to InputNumber
API, onChange
accepts a Number|String
, e.target.value
will always resolve run time error.
onChange: The callback triggered when the value is changed - function(value: number | string)
Here is an example, where I suppose in writing:
<InputNumber name='myNumber' min={1} max={100000} placeholder='Enter number' value={this.state.myNumber} onChange={handleChange}/>
You meant using a class component, because onChange={handleChange}
as you described must be a part of a class.
export default class App extends React.Component {
state = {
myNumber: 0
};
handleChange = e => {
this.setState({
myNumber: e
});
};
render() {
return (
<FlexBox>
<InputNumber
name="myNumber"
min={1}
max={100000}
placeholder="Enter number"
value={this.state.myNumber}
onChange={this.handleChange}
/>
</FlexBox>
);
}
}
handleChange
you should change the component type from InputNumber
to Input
, that's because you want to access name="myNumber"
property.handleChange = e => {
e.persist();
this.setState({
[e.target.name]: e.target.value
});
};
InputNumber
and implement handleChange
as curried function: handleChange = name => e => {
this.setState({
[name]: e
});
};
Check the example of both approaches:
class AppInputNumber extends React.Component {
state = {
myNumber: 0,
myNumber2: 0,
myNumber3: 0
};
handleChange = name => e => {
this.setState({
[name]: e
});
};
render() {
return (
<FlexBox>
<InputNumber
min={1}
max={100000}
placeholder="Enter number"
value={this.state.myNumber}
onChange={this.handleChange('myNumber')}
/>
<InputNumber
min={1}
max={100000}
placeholder="Enter number"
value={this.state.myNumber2}
onChange={this.handleChange('myNumber2')}
/>
<InputNumber
min={1}
max={100000}
placeholder="Enter number"
value={this.state.myNumber3}
onChange={this.handleChange('myNumber3')}
/>
</FlexBox>
);
}
}
export default class App extends React.Component {
state = {
myNumber: 0,
myNumber2: 0,
myNumber3: 0
};
handleChange = e => {
e.persist();
this.setState({
[e.target.name]: e.target.value
});
};
render() {
return (
<FlexBox>
<Input
name="myNumber"
min={1}
max={100000}
type="number"
placeholder="Enter number"
value={this.state.myNumber}
onChange={this.handleChange}
/>
<Input
name="myNumber2"
min={1}
max={100000}
type="number"
placeholder="Enter number"
value={this.state.myNumber2}
onChange={this.handleChange}
/>
<Input
name="myNumber3"
min={1}
max={100000}
type="number"
placeholder="Enter number"
value={this.state.myNumber3}
onChange={this.handleChange}
/>
<AppInputNumber />
</FlexBox>
);
}
}
Upvotes: 0
Reputation: 22
I am not sure but if the e
is an event object, try this
e.target.getAttribute('name')
Upvotes: -1