Функциональные vs классовые компоненты
В мире React разработки есть два способа написать компонент React. Один использует функцию, а другой использует класс. В последнее время все более популярными становятся функциональные компоненты, так почему же это?
Самый простой способ определить компонент в React - написать функцию Javascript.
Это просто функция которая принимает props и возвращает элемент React. Но вы также можете использовать синтаксис ES6 для написания компонентов.
Обе версии эквивалентны и дадут вам одинаковый результат. Вы можете спросить себя: "Когда мне использовать функцию, а когда классовый компонент?"
1. Различия между функциональными и классовыми компонентами.
Наиболее очевидное различие - это синтаксис. Функциональный компонент - это простая функция JavaScript, которая принимает props в качестве аргумента и возвращает элемент React.
Компонент класса требует, чтобы вы расширили класс React.Component и создали функцию рендеринга, которая возвращает элемент React. Для этого потребуется больше кода.
Если вы посмотрите на транслированный код Babel, вы также увидите некоторые важные отличия:
2. Передача props.
Передача props может сбивать с толку, но давайте посмотрим, как они написаны как в классовых, так и в функциональных компонентах. Допустим, мы передаем props имени «John», как показано ниже.
Внутри функционального компонента мы передаем props в качестве аргумента функции. Обратите внимание, что здесь мы используем деструктуризацию. В качестве альтернативы мы можем написать компонент и без нее:
В этом случае вы должны использовать props.name вместо name.
Поскольку это класс, вам нужно использовать this для ссылки на props. И, конечно же, мы можем использовать деструктуризацию, чтобы получить имя внутри props, используя компоненты на основе классов.
3. Использование state.
Использование state в функциональных компонентах:
Чтобы использовать state в функциональном компоненте, нам нужно использовать useState хук, который принимает initial state. Мы начинаем с 0 щелчков, поэтому initial state счетчика будет 0.
Конечно, у вас могут быть разные initial state, включая null, строку или даже объект - любой тип, который позволяет JavaScript. А с левой стороны, поскольку useState возвращает текущее состояние и функцию, которая его обновляет, мы деструктурируем массив следующим образом. Если вас немного смущают два элемента массива, вы можете рассматривать их как состояние и его установщик. В этом примере мы назвали их count и setCount, чтобы облегчить понимание связи между ними.
Использование state в классовых компонентах:
Идея все та же, но компонент класса обрабатывает состояние немного иначе. Во-первых, нам нужно понять важность конструктора React.Component. Вот определение из официальной документации:
«Конструктор компонента React вызывается перед его монтированием. При реализации конструктора для подкласса React.Component вы должны вызывать super(props) перед любым другим оператором. В противном случае this.props будет неопределенным в конструкторе, что может привести к ошибкам ».
По сути, без реализации конструктора и вызова super(props) все переменные состояния, которые вы пытаетесь использовать, будут неопределенными. Итак, давайте сначала определим конструктор. Внутри конструктора вы создадите объект состояния с ключом состояния и начальным значением. А внутри JSX мы используем this.state.count для доступа к значению ключа состояния, который мы определили в конструкторе для отображения счетчика. Сеттер почти такой же, только другой синтаксис.
В качестве альтернативы вы можете написать функцию onClick. Помните, что функция setState принимает аргумент(ы) state, при необходимости props(необязательно).
4. Методы жизненного цикла.
Наконец, поговорим о жизненных циклах. Как вы уже знаете, жизненные циклы играют важную роль во время рендеринга. Тем из вас, кто переходит от компонентов класса к функциональным компонентам, должно быть интересно, что может заменить такие методы жизненного цикла, как componentDidMount(), componentWillUnmount() в компоненте класса. И да, есть хук, который идеально подходит для этой цели:
При монтировании (componentDidMount).
Метод жизненного цикла componentDidMount вызывается сразу после завершения первого рендеринга. Раньше был componentWillMount, который происходит до первого рендеринга, но он является устаревшим и не рекомендуется для использования в новых версиях React.
Заменив componentDidMount, мы используем хук useEffect со вторым аргументом []. Второй аргумент хука useState обычно представляет собой массив состояний, которые меняются, и useEffect будет вызываться только при этих выбранных изменениях. Но когда это пустой массив, как в этом примере, он будет вызываться один раз при монтировании. Это прекрасная замена componentDidMount.
По сути, здесь происходит то же самое: componentDidMount - это метод жизненного цикла, который вызывается один раз после первого рендеринга.
При размонтировании (componentWillUnmount).
Мы также можем использовать хук useState для unmount компонента. Но будьте осторожны, синтаксис немного другой. Что вам нужно сделать, так это вернуть функцию, которая запускается при размонтировании внутри функции useEffect. Это особенно полезно, когда вам нужно очистить подписки, такие как функция clearInterval, иначе это может вызвать серьезную утечку памяти в более крупном проекте. Одним из преимуществ использования useEffect является то, что мы можем писать функции для монтирования и размонтирования в одном и том же месте.
5. Заключение.
У обоих стилей есть свои плюсы и минусы, но я хотел бы сделать вывод, что в обозримом будущем функциональные компоненты вытеснят классовые в React.
Как мы заметили в примерах, функциональный компонент написан короче и проще, что упрощает разработку, понимание и тестирование. Использование функциональных компонентов позволяет легко избежать беспорядка и сохранить все в чистоте.
Также следует отметить, что команда React поддерживает больше хуков React для функциональных компонентов, которые заменяют или даже улучшают компоненты класса. В дальнейшем команда React говорит, что они оптимизируют производительность функциональных компонентов, избегая ненужных проверок и выделения памяти. И как бы многообещающе это ни звучало, недавно были введены новые хуки для функциональных компонентов, таких как useState или useEffect. Команда стремится постепенно внедрять функциональные компоненты с хуками в новых версиях, что означает, что нет необходимости переписывать существующие проекты, в которых используются компоненты классов, на полную совместимость с функциональными компонентами.
Опять же, в React есть много допустимых стилей кодинга. Тем не менее, я предпочитаю использовать функциональные компоненты вместо компонентов класса по причинам, перечисленным выше.
Last updated
Was this helpful?