Вместо этого переключитесь на функциональные компоненты с крючками

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

Начнем с того, почему React решил отказаться от классов.

Во-первых, классы постепенно становятся нечитаемыми, если по мере роста они хранят разную логику в одном месте. Например, в componentDidMount () вы можете разместить запрос на выборку, вы можете установить стиль для элемента или подключиться к WebSocket . Все этого происходит в одном методе жизненного цикла. Представьте себе беспорядок!

Кроме того, компоненты класса очень сбивают с толку как людей, так и машины, особенно при использовании привязки и this ключевого слова.

Компоненты класса труднее тестировать по сравнению с функциональными компонентами.

Плюс вам придется потратить дополнительное время на оптимизацию классов; рефакторинг вашего кода, изменение структуры не только конкретного компонента, но и всех связанных. Когда функциональному компоненту нужен метод жизненного цикла, вы должны переписать свой код и заменить этот компонент на компонент класса.

Итак, почему бы просто не придерживаться функциональных компонентов и не изучить хуки?

Хуки были введены в React 16.8. Короче говоря, они позволяют использовать состояние и другие функции React без написания класса (из официальной документации).

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

const [voice, setVoice] = useState(0);

В этом случае мы начинаем с создания локального состояния, инициализируя его значением 0. Мы бы написали то же самое в компоненте класса следующим образом:

state = {
  voice: 0
}

Здесь функция приращения обновляет локальное состояние при нажатии кнопки:

import React, { useState } from 'react';

function Voice() {
  const [voice, setVoice] = useState(0);

  function increment() {
    setVoice(prevState => prevState + 1);
  }
  return (
    <div>
      We counted {voice} voices today!
     <button onClick={increment}>
       Vote for the candidate
     </button>
   </div>
  );
}

Хуки также позволяют нам использовать все методы жизненного цикла в функциональном компоненте. Обработчик эффекта useEffect эквивалентен componentDidMount, componentDidUpdate и componentWillUnmount.

const getItemsFromLocalStorage = () => {
  let nominations = localStorage.getItem("nominations");
    if (nominations !== null) {
      setNominations(JSON.parse(nominations));
    }
  };

//add an empty array to prevent an infinite loop
useEffect(() => {
  getItemsFromLocalStorage();
}, []);

В приведенном выше примере я использую ловушку useEffect вместо componentDidMount. Хук эффекта будет вызван при первом обновлении DOM. Если бы я написал тот же код в компоненте класса, я бы проверил локальное хранилище, чтобы увидеть, были ли там сохранены какие-либо номинации, и если да, я бы обновил локальное состояние в componentDidMount метод жизненного цикла. Но поскольку сейчас я использую функциональные компоненты, я могу написать те же функции с помощью хуков!

Несмотря на то, что компоненты класса нельзя полностью удалить из React (представьте, сколько продуктов находится в производстве и не может быть переписано!), Я чувствую, что стоит переключиться на использование функциональных компонентов с хуками. Многие крупные библиотеки уже сделали это. Например, React Redux представил хуки useSelector и useDispatch, которые значительно упрощают подключение вашего приложения React к Redux. Просто используя эти хуки, вы можете пропустить весь процесс подключения с помощью mapStateToProps и mapDispatchToProps .

При этом использование функциональных компонентов с перехватчиками - гораздо лучший способ писать компоненты.

  • Легче отделить логику от пользовательского интерфейса, сделав их пригодными для повторного использования.
  • Вам не нужно тратить время на рефакторинг функционального компонента в компонент класса, когда вам нужно добавить состояние или методы жизненного цикла.
  • Больше не нужно беспокоиться об this или привязке.
  • Легче разделять логику с отслеживанием состояния между компонентами.