@nana141414

Можно ли передовать callback через arrow function?

Примеры из документации

1
class LoggingButton extends React.Component {
 handleClick = () => {  console.log('');  }; 

 render() {
    return (
      <button onClick={this.handleClick}>Click me</button>
    );
  }
}


2
class LoggingButton extends React.Component {
  handleClick() { console.log('');}

  render() {
        return (      
            <button onClick={() => this.handleClick()}>  Click me </button>
    );
  }
}



The problem with this syntax(2) is that a different callback is created each time the LoggingButton renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering.


Но ведь не только стрелочная функция пересоздается при перерендоре, но и сам handleClick.
При перерендоре LoggingButton, handleClick меняет ссылку и наш дочерний элемент (который получает handleClick как проп) в любом случае обновляется и не важно, передаем мы handleClick напрямую или через стрелочную функцию

Или по другому, почему onClick={this.handleClick} предпочтительнее?
  • Вопрос задан
  • 91 просмотр
Решения вопроса 2
vovaspace
@vovaspace
Frontend Engineer
При перерендоре LoggingButton, handleClick меняет ссылку

Нет.
Ответ написан
Alexandroppolus
@Alexandroppolus
кодир
В примерах используется классовый компонент. Экземпляр класса создается при появлении компонента и уничтожается при размонтировании, то есть живет всё время, пока элемент присутствует в дереве. Соответственно стрелочная функция, объявленная в классе, живет всё это время и не меняется. Причем для каждого экземпляра создается своя стрелочная функция, внутри которой this указывает на свой экземпляр (т.е. он прибит гвоздями к экземпляру при любом вызове функции). То есть эту функцию можно как есть передать в виде колбэка, потому что у неё правильный this всегда с собой.

Нестрелочная функция живет в прототипе. Она общая на все экземпляры, но this у неё определяется при её вызове. То есть её нельзя просто так передать как колбэк - будет неправильный this. И её приходится передавать вот так: () => this.handleClick(). Но из-за этого в дочерний компонент при каждом рендере родителя приходит новый проп, и он (дочерний) вынужден обновляться. Потому вариант со стрелкой лучше.

Если используются функциональные компоненты, то для изготовления более-менее постоянной функции можно применить useMemo/useCallback, или ещё более радикальное решение https://github.com/reactjs/rfcs/blob/useevent/text...
(последнее работает только для функций, которые не будут вызываться в момент рендера, а только после, как эффекты или обработчики событий. Твой вариант, в общем)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы