Binding ES Class Methods in React
The choice between using the ES class
method for declaring component in
React seems to be a decided convention within the React community. The
only issue with it the need to bind the context of this
everytime you
create a function. This way you have
The Netlify login form is an easy enough component to look at:
class LoginPage extends React.Component {
constructor(props) {
super(props);
this.state = {loginError: null};
}
onLogin(provider) {
return (event) => {
// ...
};
}
render() {
const login = () => this.onLogin.bind;
return <LoginForm handleLogin={login} loginError={this.state.loginError}/>;
}
}
Everytime you need to use a class function you have two options:
return <LoginForm handleLogin={this.onLogin.bind(this)} loginError={this.state.loginError}/>;
This option will not pass the default eslint settings, due the unpopular use of bind in jsx.
const login = () => this.onLogin
return <LoginForm handleLogin={login} loginError={this.state.loginError}/>;
The problem here is the need to create a separate function to gain access to
the lexically scoped this
. This will create a new function object every time render
is called
A new way to handling the the binding of class methods do this has arisen and it’s actually pretty nice. Just add the bind(this)
to the class’s constructor.
constructor(props) {
super(props);
// ...
this.onLogin = this.onLogin.bind(this);
}
Now you can call just call this.onLogin
directly, which save a bit
of typing and maybe a kilobyte or two in minification.
class LoginPage extends React.Component {
constructor(props) {
super(props);
// ...
this.onLogin = this.onLogin.bind(this);
}
onLogin(provider) {
return (event) => {
// ...
};
}
// this.onLogin will now just use the function defined
// in the constructor no need to create a whole new function
render() {
const login = () => this.onLogin.bind;
return <LoginForm handleLogin={this.onLogin} loginError={this.state.loginError}/>;
}
}
How do you handle binding class methods in React, what are your thoughts?
*Update: There is a great discussion on some alternative solutions to this problem here
For a better understanding on this
in JavaScript, check out the
article Gentle explanation of ‘this’ keyword in JavaScript