Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between arrow functions and regular functions inside React functional components (no longer using class components)?

Since React Hooks, I have decided to let go of React class components. I'm only dealing with hooks and functional components now.

Simple question:

I understand the difference between using an arrow function instead of a regular function inside of a class body. The arrow function would automatically bind (lexical this) to the instance of my class and I don't have to bind it in the constructor. This is nice.

But since I'm not dealing with classes anymore, I would like to know what is the difference of doing the following inside of a functional component:

function App() {

  // REGULAR FUNCTION
  function handleClick1() {
    console.log('handleClick1 executed...');
  }

  // ARROW FUNCTION
  const handleClick2 = () => {
    console.log('handleClick2 executed...');
  }

  return(
    <React.Fragment>
      <div className={'div1'} onClick={handleClick1}>
        Div 1 - Click me
      </div>
      <div className={'div2'} onClick={handleClick2}>
        Div 2 - Click me
      </div>
    </React.Fragment>
  );
}

QUESTION

Both works fine.

Is there a difference in performance? Should I favor one way instead of the other? They're both recreated on every render, correct?


NOTE ON POSSIBLE DUPLICATES

I really don't think this is a duplicate question. I know there are plenty of questions about the difference between arrows and regulars, but I want to know from the perspective of a React functional component and how React handles with it. I've looked around and didn't find one.


CODE SNIPPET FOR TESTING

function App() {
  
  function handleClick1() {
    console.log('handleClick1 executed...');
  }
  
  const handleClick2 = () => {
    console.log('handleClick2 executed...');
  }
  
  return(
    <React.Fragment>
      <div className={'div1'} onClick={handleClick1}>
        Div 1 - Click me
      </div>
      <div className={'div2'} onClick={handleClick2}>
        Div 2 - Click me
      </div>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
.div1 {
  border: 1px solid blue;
  cursor: pointer;
}

.div2 {
  border: 1px solid blue;
  cursor: pointer;
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
like image 677
cbdeveloper Avatar asked May 03 '19 11:05

cbdeveloper


People also ask

What is the difference between arrow function and normal function in react?

In regular function, arguments will give you list of parameter passed in function, In arrow function arguments is not defined. In regular function, you always have to return any value, but in Arrow function you can skip return keyword and write in single line. In arrow function parameters should be unique.

What is the difference between the arrow function is es6 and traditional function?

Unlike regular functions, arrow functions do not have their own this . Arguments objects are not available in arrow functions, but are available in regular functions. Regular functions created using function declarations or expressions are 'constructible' and 'callable'.

What is the difference between functional component and class component in react?

Methods like componentWillMount, componentDidUpdate, etc., while functional component doesn't because these are simple JS functions that accept props and return its elements. In contrast, the class component has a render method that extends its Component. However, it had changed when Hooks came to the introduction.


2 Answers

Beside the differences you've already pointed out (lexical scope), arrow functions (and function expressions) are not hoisted, and as such cannot be called before they are defined. See my example. This is in my opinion not a problem, since code that relies on hoisting is much harder to reason about.

React really doesn't care about which one you use (nor can it detect it).

const A = () => {
  const name = getName();
  
  function getName() {
    return 'praffn';
  }
  
  // Will not work
  // const getName = () => 'praffn';
  
  return <p>Hi, {name}</p>;
}

ReactDOM.render(<A/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>
like image 165
Phillip Avatar answered Oct 15 '22 09:10

Phillip


Since you are not accessing the this context, both will both behave the same.

To understand more, you can check how babel is transpiring to the ECMA:

 const handleClick2 = () => {
    console.log('handleClick2 executed...');
    this.x=3
 }

will be transpiled as:

"use strict";

var _this = void 0;

var handleClick2 = function handleClick2() {
  console.log('handleClick2 executed...');
  _this.x = 3;
};

Link to babel notepad

like image 33
ykaragol Avatar answered Oct 15 '22 10:10

ykaragol