Советы и рекомендации по предотвращению головной боли.

Мотивация

Прошло около 2,5 лет с тех пор, как я впервые увидел ключевое слово React с расширением файла .js.

Поскольку тогда я был неопытным разработчиком JavaScript, я понял, что в JavaScript есть что-то, но на этом все.
2,5 года могут показаться очень долгим периодом в мире программирования.

Но, пролетело. Как вспышка.

В то время, используя в основном React, я столкнулся с кучей проблем и многому научился. Эта статья о том, как избежать тех проблем, которые я считаю очень распространенными.

Мясо

Есть, конечно, более 5 вещей, которые я хотел бы упомянуть, но я хотел подчеркнуть 5 лично важных. Я постараюсь отсортировать их в некотором порядке в зависимости от этапа проекта, на котором вы будете их использовать.

1. Используйте линтер

Первым делом — настроить линтер.

Да, это первое, что я делаю при создании нового проекта React, и я считаю, что это крайне важно для продолжения. Почему? Я цитирую официальный веб-сайт ESLint (это тот, который я использую):

Найдите и устраните проблемы в вашем коде JavaScript.

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

Наряду с ESLint я использую Prettierдля форматирования кода, поэтому мне не нужно беспокоиться о новых строках, пробелах, точках с запятой и т. д.

Существует множество отличных руководств по настройке ESLint с Prettier, и я не буду здесь вдаваться в подробности.

2. Используйте хуки

Используй их. Вот и все.
Хуки — новое дополнение в React 16.8. Короче говоря, они позволяют вам использовать некоторые основные функции React, такие как методы состояния и жизненного цикла, в компонентах функции/без сохранения состояния. Вы можете забыть о занятиях и всех проблемах, которые у Вас были с ними. Если вы начали с React до хуков, вы точно знаете, о чем я говорю.
Больше нет:

  • этоключевое слово, т.е. проблемы с привязками,
  • переключение между компонентами class/stateful и function/stateless, когда вы вдруг обнаружите, что вам нужно,
  • боль при попытке повторного использования логики с отслеживанием состояния между компонентами,

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

Я нахожу крючки очень освежающими!

Когда я впервые увидел презентацию Дэна Абрамова (своего рода духовного наставника для всех разработчиков React) на React Conf 2018, у меня был своего рода эффект эврики, и я почувствовал, что это правильно.
Я призываю вас попробовать.

3. Используйте Редукс. Главное — не злоупотребляйте!

Redux — это сторонняя библиотека, используемая для управления состоянием приложений JavaScript. Наиболее важной концепцией редукса является его однонаправленный/односторонний поток данных.

Как вы можете видеть на изображении выше, проблема в сложных приложениях React возникает, когда некоторые родительские компоненты зависят от изменения состояния окрашенного компонента. Без Redux вам придется вручную отправлять это измененное состояние компонентам, которым оно нужно. Проект быстро становится громоздким. С другой стороны, Redux дает возможность автоматически обновлять эти зависимые компоненты из одного хранилища, которое заботится обо всех изменениях состояния.

Говоря о том, чтобы не злоупотреблять этим, я имел в виду, что вы должны использовать Reduxв качестве управления состоянием, но не обязательно использовать его в каждом проекте. Я видел много разработчиков, которые использовали его как шаблон для запуска нового проекта. Это более чем ненужно, если ваш проект не требует этого, потому что процесс установки не прост (особенно для новичков), вам нужно установить несколько пакетов, а ваш проект значительно больше. Вопрос — когда его использовать?

Если вы думаете, нужен ли вам Redux — скорее всего, нет.

Другими словами, вы будете знать, когда вам это нужно. Вы наверняка узнаете трудности при попытке передать реквизит с одной ветки дерева на другую.

Помимо Redux, это еще несколько решений, таких как Context, которыеупакованы в React. Кажется, что это стало более популярным, когда появились хуки. Я не буду вдаваться в подробности, но лично он все еще отстает от Redux, например. из-за отсутствия чего-то вроде инструментов разработки Redux. Это не значит, что он не станет лучшим выбором в будущем из-за какого-то большого преимущества — не нужно ничего устанавливать или настраивать, т. е. все, что вам нужно, уже есть в библиотеке React.

4. Деструктурировать реквизит

Один из самых простых способов улучшить свой код — использовать деструктурирование свойств. Деструктуризация — это функция, представленная в ES6. Это позволяет Вам легко извлекать несколько фрагментов данных из массива или объекта.
Это помогает:

  • читабельность,
  • сокращение строк кода.

Представьте себе этот объект:

const person = {
  firstName: "Lebron",
  lastName: "James",
  city: "LA"
}

До ES6 вы должны получить к нему доступ следующим образом:

const firstName = person.firstName
const lastName = person.lastName
const city = person.city

После ES6 у нас есть что-то вроде этого, что эквивалентно приведенному выше примеру:

const { firstName, lastName, city } = person;

Тогда мы можем просто использовать его так:

console.log(firstName) // Lebron
console.log(lastName) // James
console.log(city) // LA

Это особенно важно при написании компонентов React. Нет необходимости получать доступ к значению каждого реквизита с помощью props.somethingили даже this.props.something при использовании в компонентах класса.

Существует 2 подхода в зависимости от того, пишете ли вы функциональный или классовый компонент.

//parent component
const UserList = () => {
 const person = {
   firstName: "Lebron",
   lastName: "James",
   city: "LA"
 }
return (
     <User person={person}/>
 );
});

Использование в функциональном компоненте:

//child component
const User = ({ firstName, lastName, city }) => {
 return (
  <>
   <div>{firstName}</div>
   <div>{lastName}</div>
   <div>{city}</div>
  </> 
)};

Использование в компоненте класса:

//child component
class User extends React.Component {
  render() {
    const {firstName, lastName, city} = this.props;
     return (
      <>
        <div>{firstName}</div>
        <div>{lastName}</div>
        <div>{city}</div>
      </>
     );
  }
}

5. Оптимизируйте код

Существует множество инструментов для оптимизации вашего проекта React, таких как Profiler API. Я не буду вдаваться в подробности здесь, но обязательно посмотрите. Я хочу упомянуть один простой способ запретить React отображать компонент, когда в этом нет необходимости — React memo.
Это, вероятно, имеет место в ситуациях, когда компонент:

  • рендерится часто,
  • повторный рендеринг с теми же реквизитами,
  • содержит приличное количество элементов пользовательского интерфейса.

Итак, если мы возьмем пример компонента User, который я упомянул в деструктуризации реквизита, компонент User (дочерний) будет повторно отображаться каждый раз, когда компонент UserList (родительский) перерисовывается. -оказывать. Даже если реквизиты пользователя не меняются, что поначалу странно, но так оно и работает. Это может быть очень сложно, когда компонент повторного рендеринга использует много элементов пользовательского интерфейса или когда компонент UserList отображает список компонентов User. Самый примитивный, но и самый быстрый способ проверить, так ли это на вашем компоненте, — это «старый добрый» console.log(), который вы можете поместить в свой дочерний компонент, чтобы увидеть, сколько раз компонент визуализируется. Если вы обнаружите, что это происходит более чем достаточно раз, пришло время что-то с этим делать, и решение простое. Просто оберните свой функциональный компонент с помощью memo().

const User = memo(({ firstName, lastName, city }) => {
 return (
  <>
   <div>{firstName}</div>
   <div>{lastName}</div>
   <div>{city}</div>
  </> 
 )
});

Теперь компонент будет перерисовываться только при изменении одного из его реквизитов (firstName, lastName, city). Следует отметить, что его можно использовать только в функциональных компонентах. Для компонентов класса shouldComponentUpdate() или PureComponent делают то же самое.

Вывод

Я хотел бы отметить, что это 5 личныхсоветов, которые вы можете принять или нет. Возможно, в ближайшие 2,5 года у меня появятся какие-то другие мнения, совершенно отличные от тех, что я изложил здесь. Увидим. Впрочем, буду рад, если кто-то что-то вынес из этой статьи. Удачного кодирования :).