Разница между функциями стрелок и обычными функциями внутри функциональных компонентов React (больше не использует компоненты класса)? - PullRequest
2 голосов
/ 03 мая 2019

Начиная с React Hooks, я решил отпустить компоненты класса React.Сейчас я имею дело только с хуками и функциональными компонентами.

Простой вопрос:

Я понимаю разницу между использованием функции стрелки вместо обычной функции внутритело класса.Функция стрелки будет автоматически связывать ( лексический this ) с экземпляром моего класса, и мне не нужно связывать его в конструкторе.Это хорошо.

Но так как я больше не имею дело с классами, я хотел бы знать, в чем отличие выполнения следующих действий внутри функционального компонента:

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>
  );
}

ВОПРОС

Оба отлично работают.

Есть ли разница в производительности? Должен ли я отдавать предпочтение в одну сторону вместо другого? Они оба воссоздаются при каждом рендере, правильно?


ПРИМЕЧАНИЕ ПО ВОЗМОЖНЫМ ДУБЛИКАМ

Я действительно не думаю, что это дублирующий вопрос.Я знаю, что есть много вопросов о разнице между стрелками и регулярами, но я хочу знать с точки зрения функционального компонента React и того, как React справляется с этим.Я огляделся и не нашел.


КОД ОТНОШЕНИЯ ДЛЯ ТЕСТИРОВАНИЯ

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>

Ответы [ 2 ]

4 голосов
/ 03 мая 2019

Кроме различий, которые вы уже указали (лексическая область действия), функции стрелок (и выражения функций) не подняты, и поэтому не могут быть вызваны до того, как они будут определены. Смотрите мой пример. На мой взгляд, это не проблема, так как код, основанный на подъеме, гораздо сложнее рассуждать.

Реакту действительно все равно, какой вы используете (и не может его обнаружить).

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>
1 голос
/ 03 мая 2019

Поскольку вы не обращаетесь к контексту this, оба будут вести себя одинаково .

Чтобы понять больше, вы можете проверить, как бабель попадает в ECMA:

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

будет передаваться как:

"use strict";

var _this = void 0;

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

Ссылка на блокнот Babel

...