I'm trying to follow the no-bind rule for React using the pattern that they have recommended with ES6 classes:
class Foo extends React.Component {
constructor() {
super();
this._onClick = this._onClick.bind(this);
}
render() {
return (
<div onClick={this._onClick}>
Hello!
</div>
);
}
_onClick() {
// Do whatever you like, referencing "this" as appropriate
}
}
However, when I need to pass arguments in to _onClick
, what needs to change?
I've tried something like:
import {someFunc} from 'some/path';
class Foo extends React.Component {
constructor() {
super();
this._onClick = this._onClick.bind(this, a, b);
}
render() {
const {
prop1,
prop2
} = this.props;
return (
<div onClick={this._onClick(prop1, prop2}>
Hello!
</div>
);
}
_onClick = (a, b) => {
someFunc(a, b);
}
}
However, this does not work. What needs to be altered?
I'm trying to follow the no-bind rule for React using the pattern that they have recommended with ES6 classes:
class Foo extends React.Component {
constructor() {
super();
this._onClick = this._onClick.bind(this);
}
render() {
return (
<div onClick={this._onClick}>
Hello!
</div>
);
}
_onClick() {
// Do whatever you like, referencing "this" as appropriate
}
}
However, when I need to pass arguments in to _onClick
, what needs to change?
I've tried something like:
import {someFunc} from 'some/path';
class Foo extends React.Component {
constructor() {
super();
this._onClick = this._onClick.bind(this, a, b);
}
render() {
const {
prop1,
prop2
} = this.props;
return (
<div onClick={this._onClick(prop1, prop2}>
Hello!
</div>
);
}
_onClick = (a, b) => {
someFunc(a, b);
}
}
However, this does not work. What needs to be altered?
Share Improve this question edited Feb 14, 2017 at 17:09 TheRealFakeNews asked Feb 14, 2017 at 16:47 TheRealFakeNewsTheRealFakeNews 8,15323 gold badges77 silver badges130 bronze badges 1 |4 Answers
Reset to default 8The call to bind
in the constructor should only pass this
as a single argument.
this._onClick = this._onClick.bind(this);
Here you are overwriting the property this._onClick
with a new one that has the correct this
bound. If your function takes two arguments, then you should pass those as normal at call time.
Passing additional arguments to bind
means that the function returned already has those arguments supplied - in your attempt the _onClick
function will always have its first two arguments undefined
, as a
and b
have no value in the constructor.
Now that you have bound this
to your function, you can access this.props
from within there, rather than having to pass arguments:
import {someFunc} from 'some/path';
class Foo extends React.Component {
constructor() {
super();
this._onClick = this._onClick.bind(this);
}
render() {
return (
<div onClick={this._onClick}>
Hello!
</div>
);
}
_onClick() {
const {
prop1,
prop2
} = this.props;
someFunc(prop1, prop2);
}
}
You should use partial application
. Basically you initialise your onClick function with the parameters you want, and the onClick function will return a new function to be called when the div is clicked.
import {someFunc} from 'some/path';
class Foo extends React.Component {
render() {
return (
<div onClick={this._onClick(prop1, prop2)}>
Hello!
</div>
);
}
_onClick = (a, b) => {
return () => someFunc(a, b);
}
}
PS: this only applies if your parameters a
and b
are not part of your this.props
, if they are then you should just do as Tom Fenech
said.
To answer your question there is nothing special you have to do in order to pass arguments to your this._onClick
function.
the proper revised code will be:
class Foo extends React.Component {
constructor() {
super();
this._onClick = this._onClick.bind(this);
}
render() {
return (
<div onClick={() => this._onClick(1, 2)}>
Hello!
</div>
);
}
_onClick = (a, b) => {
console.log(a, b);
}
}
Secondly, the way you are calling this._onClick
is not the right way to invoke a function on click
.
Right now what is happening that on each render process your function is getting called because you didn't pass the function as an argument rather you invoked that function and assigned its returned value to the onClick prop.
you have to do this like:
render() {
return (
<div onClick={() => this._onClick(prop1, prop2)}>
Hello!
</div>
);
}
By Invoking your function this way you ensure the this._onClick
will get called when click event occurs.
Another method is to use Babel stage 1 autobind and skip the constructor.
import {someFunc} from 'some/path';
class Foo extends React.Component {
_onClick = () => {
const {
prop1,
prop2
} = this.props;
someFunc(prop1, prop2);
}
render() {
return (
<div onClick={this._onClick}>
Hello!
</div>
);
}
}
<div onClick={this._onClick}>
– Matteo Tassinari Commented Feb 14, 2017 at 16:50