Reputation: 837
In the following code, I have the "Supplier Name" TextField set to all Upper Case letters. If I wanted to add this to the "Comments" TextField, I know that I can just add more handleChange events and name them differently. Is there a way to use the same handleChange event for multiple TextFields since I want to do the exact same thing?
import * as React from "react";
import { TextField} from 'office-ui-fabric-react/lib/TextField';
export interface StackOverflowState {
value: string;
}
export default class StackOverflow extends React.Component<{}, StackOverflowState> {
public state: StackOverflowState = { value: '' };
render() {
this.handleChange = this.handleChange.bind(this);
;
return (
<div className="ms-welcome">
<TextField
label="Supplier Name"
styles={{ root: { width: 150 } }}
onChange={this.handleChange.bind(this)}
value={this.state.value}
/>
<TextField
label="Comments"
styles={{ root: { width: 300 } }}
/>
</div>
);
}
handleChange(event) {
this.setState({value: event.target.value.toUpperCase()});
}
}
Upvotes: 0
Views: 1457
Reputation: 2897
Try using the bind a little more :)
import * as React from "react";
import { TextField} from 'office-ui-fabric-react/lib/TextField';
export interface StackOverflowState {
value: string;
comments: string;
}
export default class StackOverflow extends React.Component<{}, StackOverflowState> {
public state: StackOverflowState = { value: '', comments: '' };
private const handleChange = (stateField: keyof StackOverflowState) => (event) {
this.setState({ [stateField]: event.target.value.toUpperCase()});
}
render() {
return (
<div className="ms-welcome">
<TextField
label="Supplier Name"
styles={{ root: { width: 150 } }}
onChange={this.handleChange('value')}
value={this.state.value}
/>
<TextField
label="Comments"
onChange={this.handleChange.('comments')}
styles={{ root: { width: 300 } }}
/>
</div>
);
}
}
Upvotes: 1
Reputation: 15186
Some notice points:
.bind(this)
inside render(), optionally use arrow function.constructor()
to init state for classical component.[key: string]: State[keyof State]
to enable choosing attribute by a string.Further, we can:
import * as React from "react";
import { TextField } from "office-ui-fabric-react/lib/TextField";
export interface State {
[key: string]: State[keyof State];
inputA: string;
inputB: string;
}
export default class App extends React.Component<{}, State> {
constructor(props: {}) {
super(props);
this.state = {
inputA: "",
inputB: ""
};
}
handleChange = (field: string) => (event: any) => {
const value = event.target.value.toUpperCase();
this.setState({ [field]: value });
};
render() {
console.log(this.state);
return (
<div className="ms-welcome">
<TextField
label="Supplier Name"
styles={{ root: { width: 150 } }}
onChange={this.handleChange("inputA")}
value={this.state["inputA"]}
/>
<TextField
label="Comments"
styles={{ root: { width: 300 } }}
onChange={this.handleChange("inputB")}
value={this.state["inputB"]}
/>
</div>
);
}
}
Upvotes: 2
Reputation: 1037
To handle multiple inputs with single event handler. You have to give unique names to your input values and you can write your handle change based on unique names.
<div className="ms-welcome">
<TextField
name="input1"
onChange={this.handleChange.bind(this)}
value={this.state.value}
/>
<TextField
name="input2"
onChange={this.handleChange.bind(this)}
value={this.state.value}
/>
</div>
Now you can simply write handle change based on unique names applied to input fields
HandleChange (e) {
this.setState({[e.target.name]: e.target.value})
}
When event comes from first input e.target.name
will be input1 and when event comes from second input e.target.name
will be input2.
Upvotes: 1
Reputation: 22935
You can use object as state containing keys as field names and values against respective field names
state = { values : {} };
onChange = (name, e) => {
this.setState(state => ({ values: { ...state.values, [name]: e.target.value } }));
// If e.target.name contains field name, no need to add extra name parameter in this method, you can use that as name
}
<TextField
label="Supplier Name"
styles={{ root: { width: 150 } }}
onChange={e => this.handleChange('supplierName', e)}
value={this.state.values.supplierName}
/>
<TextField
label="Comments"
styles={{ root: { width: 300 } }}
onChange={e => this.handleChange('comments', e)}
value={this.state.values.comments}
/>
Upvotes: 1