Как связать функцию с хуками в React?

В основном мы связываем функции обработчика событий в конструкторе или делаем их как стрелочные функции в компонентах класса React, как показано ниже.

class Test extends Component{
  constructor(props){
    super(props);
    this.state = { count:0 };
    this.setCount = this.setCount.bind(this);
  }

  setCount() {
    this.setState({count: this.state.count + 1});
  }

  render() {
    return <button onClick = {this.setCount}>Increase</button>
  }
}

Но после того, как в React v16.7.0 были введены хуки, компоненты класса стали функциональными компонентами с состоянием.

Итак, как я могу связать функцию с крючками в функциональном компоненте?

Нет необходимости связывать функцию в функциональном компоненте, поскольку вы не используете this.

Tholle 08.11.2018 20:49

вам не нужно, если вы используете функцию стрелки

victor zadorozhnyy 08.11.2018 20:50

Хорошо, что, если я использую метод подключения Redux с mapStateToProps. Как я могу получить доступ к реквизитам в функциональном компоненте, таком как this.props, или просто в реквизитах?

Hemadri Dasari 08.11.2018 21:02

Вы просто используете props ... а не this.props

weibenfalk 08.11.2018 21:08
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
26
4
38 940
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Нет необходимости связывать функции / обратные вызовы в функциональных компонентах, поскольку в функциях нет this. В классах было важно привязать this, потому что мы хотим убедиться, что this в обратных вызовах ссылается на сам экземпляр компонента. Однако выполнение .bind в конструкторе имеет еще одно полезное свойство - создавать функции однажды в течение всего жизненного цикла компонента, и новый обратный вызов создавался не при каждом вызове render(). Чтобы инициализировать обратный вызов только один раз, используя перехватчики React, вы должны использовать useCallback.

Классы

class Foo extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    console.info('Click happened');
  }

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

Хуки

function Foo() {
  const memoizedHandleClick = useCallback(
    () => {
      console.info('Click happened');
    },
    [], // Tells React to memoize regardless of arguments.
  );
  return <Button onClick = {memoizedHandleClick}>Click Me</Button>;
}

Спасибо. Разве я не могу написать функцию обработчика событий, такую ​​как const memoizedHandleClick = () => {console.info ('Нажатие произошло'); }?

Hemadri Dasari 12.11.2018 16:49

@ Думай дважды, да, ты можешь. Но он будет воссоздавать обработчик при каждом рендеринге (так же, как при использовании стрелочных функций в render() на основе классов).

skyboyer 12.11.2018 16:58

Хорошо, что такое useCallback? Это предопределенное имя?

Hemadri Dasari 12.11.2018 16:59

Да это еще один крючок. Вы читали документы? Вы должны проверить весь раздел о хуках: reactjs.org/docs/hooks-intro.html

Yangshun Tay 12.11.2018 19:13

Вы могли бы также написать компонент Foo, описанный выше, таким образом и сэкономить время на вводе текста. Обратите внимание на синтаксис handleClick ... он определяет закрытие handleClick как поле в Foo, а не как метод. Это избавляет вас от необходимости использовать привязку для перезаписи ссылки на объект handleClick в конструкторе. (Кроме того, вам не нужно определять конструктор, если вы просто вызываете «супер»!)

class Foo extends Component {
  handleClick = () => {
    console.info('Click happened');
  }

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

Точно так же для вашего исходного примера просто объявите state и setCount напрямую и упростите свой код:

class Test extends Component{
  state = {count: 0}

  setCount = () => {
    this.setState({count: this.state.count + 1});
  }

  render() {
    return <button onClick = {this.setCount}>Increase</button>
  }
}

Это просто альтернативный подход к решению проблемы привязки для компонентов класса. OP спрашивает, как это решается для функциональных компонентов.

Jamie Kudla 18.03.2019 18:06

Люди приходят в SO и копируют код. Оставьте этот ответ здесь, чтобы сообщество React не ошибалось в запоминании всего и, возможно, выполняло больше работы, чем необходимо.

Функциональные компоненты

function Foo() {
  const handleClick = function(){
    // use function statements to avoid creating new instances on every render
    // when you use `bind` or arrow functions
    console.info('memoizing can lead to more work!')
  };
  return <Button onClick = {handleClick}>Click Me</Button>;
}

Совет: посмотрите, какой код передается при использовании useCallback, и посмотрите, нужен ли он, прежде чем вставлять его. Если вы не уверены, что он вам нужен, вероятно, нет. и чтобы быть уверенным, что это приносит вам пользу, профилируйте его.

Другие вопросы по теме