Начиная с React Hooks, я решил отказаться от компонентов класса React. Сейчас я имею дело только с хуками и функциональными компонентами.
Простой вопрос:
Я понимаю разницу между использованием функции стрелки вместо обычной функции внутри тела класса. Функция стрелки автоматически привязывается (лексический это) к экземпляру моего класса, и мне не нужно привязывать ее в конструкторе. Это приятно.
Но так как я больше не имею дело с классами, я хотел бы знать, в чем разница делать следующее внутри функционального компонента:
function App() {
// REGULAR FUNCTION
function handleClick1() {
console.info('handleClick1 executed...');
}
// ARROW FUNCTION
const handleClick2 = () => {
console.info('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.info('handleClick1 executed...');
}
const handleClick2 = () => {
console.info('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>Любая другая информация, которую вы читали о стрелочных функциях, обычных именованных функциях и анонимных функциях, объявленных с переменными, по-прежнему применима здесь. Разницы в производительности нет между ними. И даже невозможно определить, является ли функция стрелочной функцией во время выполнения, поэтому React не может и не может обрабатывать их иначе, чем обычные функции.
Уф. Я ошибался, говоря, что не могу обнаружить функции стрелок. stackoverflow.com/questions/28222228/…, но я очень сомневаюсь, что React так делает. В основном из-за транспиляторов.
См. также stackoverflow.com/a/55784719/3731501



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Помимо различий, которые вы уже указали (лексическая область), стрелочные функции (и функциональные выражения) поднимаются нет и, как таковые, не могут быть вызваны до того, как они будут определены. Смотрите мой пример. На мой взгляд, это не проблема, так как код, основанный на подъеме, гораздо труднее рассуждать.
React действительно не заботится о том, какой из них вы используете (и не может его обнаружить).
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>Лично я не обнаружил, что поднятие функций представляет большую проблему на практике (в отличие от подъема var), и я думаю, что наличие ключевого слова function делает код более читаемым, чем если бы почти все начиналось с const. (Я подозреваю, что Facebook может иметь аналогичные причины для использования function в своих примерах.) Но, как уже указал Филипп, это стилистическое предпочтение — любой из них будет работать нормально.
@MattBrowne, на самом деле я предпочитаю использовать ключевое слово function - для меня оно намного читабельнее. Обычно я использую стрелочные функции только для однострочников и при использовании в функциях более высокого порядка. Однако я воздерживаюсь от использования подъема, когда это возможно.
@MattBrowne Я думаю, что ключевое слово function также делает код более читабельным. И я почти никогда не использую подъемную "функцию".
Поскольку вы не обращаетесь к контексту this, оба будут вести себя как тоже самое.
Чтобы понять больше, вы можете проверить, как Babel транслируется в ECMA:
const handleClick2 = () => {
console.info('handleClick2 executed...');
this.x=3
}
будет транспилирован как:
"use strict";
var _this = void 0;
var handleClick2 = function handleClick2() {
console.info('handleClick2 executed...');
_this.x = 3;
};
Доступ к this внутри стрелочной функции или объявления функции не даст никакой разницы, поскольку this будет равно undefined. Это потому что React components are written within ES6 modules, which automatically run in strict mode.
Если вы не используете
this, то разница внутри функции совершенно не имеет значения. Внешнее отличие состоит в том, что объявления функций поднимаются вверх области видимости, а назначение стрелочной функции переменной (var, const, let) — нет. Есть еще одна разница в том, чем var отличается от const и let, но это имеет значение только в том случае, если вы ссылаетесь на что-то до того, как оно будет назначено.