With constructors in es6, we are advised to bind functions early, e.g.
class App extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this); // bound early
}
handleClick() {
// do stuff
}
...
}
In ES5, we could typically call something like this.handleClick.bind(this, "foo")
if we wanted to preserve context AND send an extra argument. What is the best pattern for this with the new class syntax in ES6 React?
For instance, if my class looked like the code below, how would I best access the "foo"
and "bar
" values? (I know the answer is not bind
but this is how I could best illustrate the problem).
class App extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this); // bound early
}
handleClick(event, value) {
// do stuff with value ("foo" or "baz")
}
render() {
return (
<div>
<button onClick={this.handleClick.bind("foo")} /> // incorrect code
<button onClick={this.handleClick.bind("bar")} /> // incorrect code
</div>
)
}
}
If you want to pass a parameter to the click event handler you need to make use of the arrow function or bind the function. If you pass the argument directly the onClick function would be called automatically even before pressing the button.
In order to pass a value as a parameter through the onClick handler we pass in an arrow function which returns a call to the sayHello function. In our example, that argument is a string: 'James': ... return ( <button onClick={() => sayHello('James')}>Greet</button> ); ...
To use the addEventListener method in function components in React: Set the ref prop on the element. Use the current property on the ref to get access to the element. Add the event listener in the useEffect hook.
In ES5, we could typically call something like
this.handleClick.bind(this, "foo")
if we wanted to preserve context AND send an extra argument.
You can do exactly the same in ES6 as well. It's not like bind
was removed from the language :-)
class App extends React.Component {
constructor(props) {
super(props);
this.handleFooClick = this.handleClick.bind(this, "foo"); // bind early
}
handleClick(value, event) {
// ^^^^^^ notice the bound values come first
…
}
render() {
return (
<div>
<button onClick={this.handleFooClick} /> // use early-bound
<button onClick={this.handleClick.bind(this, "bar")} /> // bind late
<button onClick={event => this.handleClick("foobar", event)} /> // arrow function
</div>
)
}
}
Think that:
onClick={this.handleClick.bind(this)}
Is the same as:
onClick={e => this.handleClick(e)}
So you can do:
<button onClick={e => this.handleClick(e, 'foo')} />
<button onClick={e => this.handleClick(e, 'baz')} />
In the end it is all just JavaScript.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With