Avoid built-in functions in React: how to bind functions with arguments?

I am trying to follow the no-bind rule for React using the template they recommended using 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 to _onClick , what needs to be changed?

I 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 changed?

+6
source share
4 answers

The bind call in the constructor should pass only this as one argument.

 this._onClick = this._onClick.bind(this); 

Here you rewrite this._onClick property this._onClick new ones that have the correct this binding. If your function takes two arguments, you must pass them as usual during the conversation.

Passing additional arguments to bind means that the returned function already contains these arguments - in your attempt, the _onClick function _onClick always have its first two arguments undefined , since a and b do not matter in the constructor.

Now that you have bound this to your function, you can access this.props from the inside, instead of passing 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); } } 
+6
source

You must use partial application . Basically, you initialize your onClick function with the necessary parameters, and the onClick function returns a new function that will be called when you click on the div.

 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 it like Tom Fenech .

+5
source

To answer your question, you have nothing to do to pass the arguments to your this._onClick function.

The correct revised code would 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 call this._onClick is not the right way to call a function on click .

Currently, what happens in every visualization process called by your function, because you did not pass the function as an argument, but you called this function and assigned its return value to support onClick.

you need to do it like:

 render() { return ( <div onClick={() => this._onClick(prop1, prop2)}> Hello! </div> ); } 

By calling your function in this way, you guarantee that this._onClick will be called when the click event occurs.

0
source

Another method is to use autobind for Babel stage 1 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> ); } } 
0
source

Source: https://habr.com/ru/post/1014972/


All Articles