Главная Категории Контакты Поиск

Hooks vs Class компоненты

Почему стоит использовать функциональные компоненты + хуки над классовыми компонентами в React

React·26.02.2021·читать 2 мин 🤓·Автор: Alexey Myzgin

Если ты новичок в React и работал через туториалы, скорее всего, тебе доводилось сталкиваться с примерами как функциональных компонентов с хуками, так и компонентов класса, без четкого указания, какой из них следует использовать. Даже будучи опытным разработчиком, ты, возможно, всё ещё используешь компоненты класса, гадая, стоит ли их переписывать.

Если ты не нашел четкого ответа, это не удивительно, даже в официальной документации не было чётких рекомендаций до середины 2020 года.

Какой из них использовать

Официальная позиция команды React (согласно документации):

When you’re ready, we’d encourage you to start trying Hooks in new components you write. […] We don’t recommend rewriting your existing classes to Hooks unless you planned to rewrite them anyway (e.g. to fix bugs).

Итог:

  • новый код должен использовать функциональные компоненты с хуками;
  • старый код может продолжать использовать компоненты класса, если ты не хочешь переписывать.

Должен ли я тогда сосредоточиться на хуках?

Это не так просто.

Тебе по-прежнему нужны компоненты класса для построения Error Boundaries. Конечно, ты можешь зайти в npm и найти для использования библиотеку Error Boundary на основе Hook, но незнание не оправдывает добавление ещё одной зависимости в твой проект.

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

Также ты обнаружишь, что компании, которые задают вопросы по React во время собеседований, по-прежнему будут спрашивать о классах. 🤫

Нужно ли переписать старый код на основе классов для использования хуков

Как и во всем хорошем, здесь есть компромиссы.

Хуки приводят к гораздо более чистым и легким для понимания компонентам по сравнению с компонентами классов аналогичной сложности.

Чтобы проиллюстрировать мою точку зрения, сравни этот компонент, который извлекает некоторые данные из API Звездных войн, записанный сначала как класс, а затем как функциональный компонент с хуками:

import React from 'react';

export default class DataDisplayer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null,
    };
  }
  async componentDidMount() {
    const response = await fetch(
      `https://swapi.dev/api/people/${this.props.id}/`
    );
    const newData = await response.json();
    this.setState({ data: newData });
  }
  render() {
    const { data } = this.state;
    if (data) {
      return <div>{data.name}</div>;
    } else {
      return null;
    }
  }
}

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

Не знаю, как у тебя, но мой мыслительный процесс при просмотре классов такой:

  • хорошо, я нахожусь в componentDidMount, поэтому буду получать данные здесь;

  • выполняем рендеринг, поэтому этот код запускается каждый раз;

  • нужно добавить дополнительную функциональность … хм, какой метод жизненного цикла снова используется?.

С другой стороны, есть хуки:

import React, { useEffect, useState } from 'react';

export default function DataDisplayer(props) {
  const [data, setData] = useState('');

  useEffect(() => {
    const getData = async () => {
      const response = await fetch(`https://swapi.dev/api/people/${props.id}/`);
      const newData = await response.json();
      setData(newData);
    };
    getData();
  }, [props.id]);

  if (data) {
    return <div>{data.name}</div>;
  } else {
    return null;
  }
}

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

Это главное преимущество переписывания на хуки - опыт разработчика улучшается, поскольку требуется меньше времени, чтобы понять, что делает каждый компонент.

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

Что дальше делать

Я рекомендую следующий подход, который хорошо работает. Весь новый код должен быть написан как функциональные компоненты с хуками. Существующий код следует переписывать только в том случае, если он часто изменяется (например, если ты исправляешь ошибку или добавляешь функциональность, найди время, чтобы заменить компонент на хуки).

Website, name & logo
Copyright © 2022. Alex Myzgin