Proper use of arrow functions in React

I use ReactJS with Babel and Webpack and using ES6, as well as the proposed class fields for arrow functions. I understand that arrow functions make things more efficient with the help of not recreating the functions that each renders , similar to how binding in the constructor works. However, I am not 100% sure if I use them correctly. The following is a simplified section of my code in three different files.

My code is:

Main.js

prevItem = () => {
    console.log("Div is clicked")
}

render(){
    return (
         <SecondClass prevItem={this.prevItem} />
    )
}

SecondClass.js

<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />

ThirdClass.js

<div onClick={()=>{this.props.onClick()}}>Previous</div>

Question:

Does my code above work correctly using the arrow function? I noticed that for SecondClass.js I could also use:

<ThirdClass type="prev" onClick={this.props.prevItem} />

, ES6 ? div?

+32
5

, , , , .

. , Arrow. Arrow function, everytime, , bind.

<div onClick={()=>{this.onClick()}}>Previous</div>

, , this.onClick.

onClick = () => {
    console.log("Div is clicked")
}

, React An arrow function does not have its own this; the this value of the enclosing execution context is used. . binding works is constructor. proposed class fields for arrow functions, ES6,

, , , , . , this question .

Arrow function prevItem, , , React.

prevItem = () => {
    console.log("Div is clicked")
}

render(){
    return (
         <SecondClass prevItem={this.prevItem} />
    )
}

, prevItem , using bind or arrow function, prevItem i.e Main.js React. prevItem - ,

<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />

<div onClick={()=>{this.props.onClick()}}>Previous</div>

, SecondClass ThirdClass . ,

<ThirdClass type="prev" onClick={this.props.prevItem} />

<div onClick={this.props.onClick}>Previous</div>

.

, ThirdClass SecondClass, Arrow function bind in render. How to Avoid binding in Render method

+31

   , , ,

.

this , "" . , .

render.

onClick={() => {}}

.

onClick={this.myHandler}


( , ), , class this:

myHandler(){
  //  this.setState(...)
}

bind class.
constructor, :

constructor(props){
  super(props);
  this.myHandler = this.myHandler.bind(this);
}

, bind class, , , this:

myHandler = () => {
  //  this.setState(...)
}

:

<div onClick={this.myHandler}></div> 

:

<div onClick={() => this.myHandler(someParameter)}></div>

event, , .

, .
( , ).

:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [{ name: 'item 1', active: false }, { name: 'item 2', active: true }],
    }
  }
  toggleITem = (itemName) => {
    this.setState(prev => {
      const nextState = prev.items.map(item => {
        if (item.name !== itemName) return item;
        return {
          ...item,
          active: !item.active
        }
      });
      return { items: nextState };
    });
  }
  render() {
    const { items } = this.state;
    return (
      <div>
        {
          items.map(item => {
            const style = { color: item.active ? 'green' : 'red' };
            return (
              <div
                onClick={() => this.toggleITem(item.name)}
                style={style}
              >
                {item.name}
              </div>
          
          )})
        }
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Hide result

.
, , data handler .

, , data .

:

class Item extends React.Component {
  onClick = () => {
    const { onClick, name } = this.props;
    onClick(name);
  }
  render() {
    const { name, active } = this.props;
    const style = { color: active ? 'green' : 'red' };
    return (<div style={style} onClick={this.onClick}>{name}</div>)
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [{ name: 'item 1', active: false }, { name: 'item 2', active: true }],
    }
  }
  toggleITem = (itemName) => {
    this.setState(prev => {
      const nextState = prev.items.map(item => {
        if (item.name !== itemName) return item;
        return {
          ...item,
          active: !item.active
        }
      });
      return { items: nextState };
    });
  }
  render() {
    const { items } = this.state;
    return (
      <div>
        {
          items.map(item => {
            return <Item {...item} onClick={this.toggleITem} />
          })
        }
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Hide result

:
, .
, instance class ( ).
.

, , .

:

class MyClass {
  myMethod(){}  
  myOtherMethod = () => {}
}

Babel :

var _createClass = function() {
  function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }
  return function(Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);
    if (staticProps) defineProperties(Constructor, staticProps);
    return Constructor;
  };
}();

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var MyClass = function() {
  function MyClass() {
    _classCallCheck(this, MyClass);

    this.myOtherMethod = function() {};
  }

  _createClass(MyClass, [{
    key: "myMethod",
    value: function myMethod() {}
  }]);

  return MyClass;
}();
+46

,

<ThirdClass type="prev" onClick={()=>this.props.prevItem()} />

, ThirdClass, prevItem. .

<ThirdClass type="prev" onClick={()=>this.props.prevItem(firstArgument, secondArgument)} />

<ThirdClass type="prev" onClick={this.props.prevItem} />

ThirdClass.

apporaches , , . , es6,

+6

JavaScript curring, , :

clickHandler = someData => e => this.setState({
  stateKey: someData
});

JSX :

<div onClick={this.clickHandler('someData')} />

clickHandler someData e clickHandler. .

:

clickHandler = someData => () => this.setState({
  stateKey: someData
});

e, .

+4

.

...

prevItem(){
  console.log("Div is clicked")
}

, ...

class MyComponent extends Component {
  constructor(props) {
    super(props)
    this.prevItem = this.prevItem.bind(this)
  }

  prevItem() { ... }
}

, , , , , this javascript.

. bind in constructor , .

+3

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


All Articles