Reputation: 27793
I just read this highly enlightening article today:
https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f
The article uses the following example to show how to pre-bind functions to prevent components from needless re-rendering:
class App extends PureComponent {
constructor(props) {
super(props);
this.update = this.update.bind(this);
}
update(e) {
this.props.update(e.target.value);
}
render() {
return <MyInput onChange={this.update} />;
}
}
This makes sense, though I can't figure out how to pass an argument to the function without using bind or () => this.myFunc('some arg')
. Example:
<div>
<TextField
floatingLabelText="Email"
required
value={this.state.email}
onChange={e => this.setState({email: e.target.value})}
/>
</div>
<div>
<TextField
type="password"
floatingLabelText="Password"
required
value={this.state.password}
onChange={e => this.setState({password: e.target.value})}
/>
</div>
I'm not sure how to refactor this to not use binding. I've got this class method as a starting point:
_textChange(field, value) {
this.setState({
[field]: value,
});
}
But I'm not sure how to pass arguments into it from the onChange
prop and follow the suggestions laid out by the article above.
Additionally, I have code that I've refactored into this:
export default OrgList = (props) => {
const orgs = props.orgs.map((org) => {
const addEditOrg = props.onAddEditOrg.bind(null, org, 'edit');
const deleteOrg = props.onDeleteOrg.bind(null, org);
return <TableRow key={org._id}>
<TableRowColumn>{org.name}</TableRowColumn>
<TableRowColumn>
<IconButton onTouchTap={addEditOrg}>
<ModeEdit />
</IconButton>
[...]
But I'm not sure if those pre-bound functions are in the right place. Do they need to be totally outside the component?
Upvotes: 3
Views: 830
Reputation: 668
I use name attribute for this. Example:
handleChange(e) {
this.setState({[e.target.name]: e.target.value})
}
<TextField
name="email"
onChange={this.handleChange}
/>
<TextField
name="password"
onChange={this.handleChange}
/>
Upvotes: 4
Reputation: 22872
Unfortunately, you have to create separate methods which set email/password.
linkState
is noop here, since it always returns different object. Same apply to higher order function (returning anonymous function as handler).
I would end up with this code. Event handlers are same, no unnecessary rendering is triggered this way.
setEmail(e) {
this.setState({email: e.target.value})
}
setPassword(e) {
this.setState({password: e.target.value})
}
<TextField
onChange={this.setEmail}
/>
<TextField
onChange={this.setPassword}
/>
Upvotes: 1