React — это библиотека JavaScript, и на сегодняшний день это самая популярная и ведущая в отрасли библиотека для разработки интерфейсов.
JavaScript — это язык со свободной типизацией, и в результате он перехватывает время выполнения. В результате ошибки JavaScript обнаруживаются очень поздно, что может привести к неприятным ошибкам. Как библиотека JavaScript, React наследует эту проблему.
Чистый код — это последовательный стиль программирования, упрощающий написание, чтение и поддержку кода. Любой может написать код, понятный компьютеру, но хорошие разработчики пишут чистый код — код, понятный людям.
Чистый код — это стиль разработки, ориентированный на читателя, который улучшает наше качество программного обеспечения и ремонтопригодность.
Написание чистого кода включает в себя написание кода с четкими и простыми шаблонами проектирования, которые облегчают людям чтение, тестирование и поддержку. Следовательно, чистый код может снизить стоимость разработки программного обеспечения. И это потому, что принципы написания чистого кода устраняют технические долги.
В этой статье мы рассмотрим некоторые полезные шаблоны, которые можно использовать при работе с React и TypeScript.
💡 Чтобы вашей команде было проще поддерживать работоспособность кодовой базы и расставлять приоритеты в работе с техническими долгами, попробуйте расширения Stepsize VS Code и JetBrains. Они помогают инженерам создавать технические проблемы, добавлять их в спринт и постоянно устранять технический долг, не выходя из редактора.
Теперь давайте узнаем о десяти полезных шаблонах, которые можно применять при использовании React и Typescript:
1. Используйте импорт по умолчанию для импорта React
Рассмотрим код ниже:
import * as React from "react";
Хотя приведенный выше код работает, это сбивает с толку, и не рекомендуется импортировать все содержимое React, если мы его не используем. Лучше использовать экспорт по умолчанию, как показано ниже:
import React, {useContext, useState} from "react";
При таком подходе мы можем деструктурировать то, что нам нужно, из модуля react
вместо того, чтобы импортировать все содержимое.
Примечание. Чтобы использовать эту опцию, нам нужно настроить файл tsconfig.json
, как показано ниже:
{ "compilerOptions": { "esModuleInterop": true } }
В приведенном выше коде, установив esModuleInterop
в true
, мы активируем [allowSyntheticDefaultImports](https://allowsyntheticdefaultimports)
, что важно для TypeScript для поддержки нашего синтаксиса.
2. Объявляйте типы перед реализацией во время выполнения
Рассмотрим код ниже:
Приведенный выше код может быть чище и читабельнее, если мы разделим объявления времени выполнения и времени компиляции. И это делается путем объявления типов — сначала объявлений компилируемых типов.
Рассмотрим код ниже:
Теперь с первого взгляда разработчик знает, как выглядит API компонента, поскольку первая строка кода ясно показывает это.
Кроме того, мы отделили наши объявления времени компиляции от наших объявлений времени выполнения.
3. Всегда указывайте явный тип дочерних реквизитов
TypeScript отражает то, как React обрабатывает дочерние реквизиты, аннотируя его как необязательный в react.d.ts
как для функциональных, так и для классов компонентов. Следовательно, мы должны явно указать тип реквизита children
. Тем не менее, рекомендуется всегда явно аннотировать children
свойства с типом. Это полезно в тех случаях, когда мы хотим использовать children
для проецирования контента, и если наш компонент его не использует, мы можем просто аннотировать его типом never
.
Рассмотрим код ниже:
Ниже приведены некоторые допустимые типы для аннотирования дочерних реквизитов:
- Реактузел | РеактЧилд | РеактЭлемент
- Для примитива мы можем использовать строку | номер | логический
- Объект и массивы также являются допустимыми типами.
- никогда | ноль | undefined — Примечание: значения null и undefined не рекомендуются.
4. Используйте определение типа для определения состояния компонента или DefaultProps.
Рассмотрим код ниже:
Пока приведенный выше код работает, мы можем реорганизовать его для следующих улучшений:
Чтобы система типов TypeScript могла правильно выводить readonly
типы, такие как DefaultProps
и initialState
Чтобы предотвратить ошибки разработчиков, возникающие из-за случайной установки состояния: this.state = {}
Рассмотрим код ниже:
В приведенном выше коде, заморозив DefaultProps
и initialState
, система типов TypeScript теперь может вывести их как типы readonly
.
Кроме того, помечая как static defaultProps
, так и state как readonly
внутри класса, мы устраняем возможность ошибок во время выполнения, возникающих из-за установки состояния, как упоминалось выше.
5. Используйте псевдоним типа вместо интерфейса для объявления Props/State
Хотя можно использовать interface
, для согласованности и ясности лучше использовать псевдоним типа, поскольку бывают случаи, когда interface
не работает. Например, в предыдущем примере мы реорганизовали наш код, чтобы позволить системе типов TypeScript правильно выводить типы только для чтения, определяя тип состояния из реализации. Мы не можем использовать interface
с этим шаблоном, как показано в коде ниже:
6. Не используйте объявление метода в псевдониме интерфейса/типа
Это обеспечивает согласованность шаблонов в нашем коде, поскольку все члены type/inference объявляются одинаково.
Кроме того, --strictFunctionTypes
работает только при сравнении функций и не применяется к методам. Дальнейшие пояснения вы можете получить из этого выпуска ТС.
Рассмотрим код ниже:
7. Не используйте FunctionComponent
Или его сокращение FC
для определения функционального компонента!
При использовании TypeScript с React функциональные компоненты можно писать двумя способами:
- Как обычные функции, как показано в коде ниже:
Используя React.FC
или React.FunctionComponent
, как показано ниже:
Использование FC
дает некоторые преимущества, такие как проверка типов и автозаполнение для статических свойств, таких как displayName
, propTypes
и defaultProps
. Но у него есть известная проблема с нарушением defaultProps и других реквизитов: propTypes
, contextTypes
, displayName
.
FC
также предоставляет неявный тип для свойства children
, у которого также есть известные проблемы.
Кроме того, как обсуждалось ранее, API компонента должен быть явным, поэтому неявный тип для свойства children
не лучший вариант.
8. Не используйте конструктор для компонентов класса
С новым предложением полей классов больше нет необходимости использовать конструкторы в классах JavaScript. Использование конструкторов включает в себя вызов super()
и передачу props
, а это вводит ненужные шаблоны и сложность.
Мы можем написать более чистые и удобные в сопровождении компоненты класса React, используя поля класса, как показано ниже:
В приведенном выше коде мы видим, что использование полей класса требует меньше шаблонного кода, и нам не нужно иметь дело с переменной this
.
9. Не используйте публичный доступ внутри классов
Рассмотрим код ниже:
Поскольку все члены в классе имеют public
по умолчанию и во время выполнения, нет необходимости добавлять дополнительный шаблон, явно используя ключевое слово public
.
Вместо этого используйте приведенный ниже шаблон:
10. Не используйте приватный метод доступа в классе Component
Рассмотрим код ниже:
В приведенном выше коде частный метод доступа делает метод fetchProfileByID
private
только во время компиляции, поскольку это просто эмуляция TypeScript. Однако во время выполнения метод fetchProfileByID
остается общедоступным.
Существуют разные способы сделать свойства/методы закрытыми в классе JavaScript. Один из них заключается в использовании соглашения об именах с символом подчеркивания (_), как показано ниже:
Хотя на самом деле это не делает метод fetchProfileByID
приватным, он хорошо передает другим разработчикам наше намерение рассматривать указанный метод как приватный. Другие методы включают использование слабых карт, символов и переменных области видимости.
Но с новым предложением ECMAScript поля класса мы можем сделать это легко и изящно, используя частные поля, как показано ниже:
А TypeScript поддерживает новый синтаксис JavaScript для приватных полей начиная с версии 3.8 и выше.
Бонус: не используйте enum
Хотя enum
является зарезервированным словом в JavaScript, использование enum
не является стандартным идиоматическим шаблоном JavaScript.
Но если вы работаете с таким языком, как C#
или JAVA
, может возникнуть соблазн использовать перечисления. Однако есть лучшие шаблоны, такие как использование литералов типа компиляции, как показано ниже:
Заключение
Использование TypeScript, без сомнения, добавляет в ваш код много дополнительного шаблона, но польза того стоит.
Чтобы сделать ваш код чище и лучше, не забудьте внедрить надежный процесс TODO/issue. Это поможет вашей инженерной команде получить представление о техническом долге, совместно работать над проблемами кодовой базы и лучше планировать спринты.
Этот пост был написан для блога Управление техническим долгом Лоуренсом Иглзом — полноценным разработчиком Javascript, любителем Linux, страстным наставником и техническим писателем. Лоуренс сочетает в себе креативность и простоту. Когда он не программирует и не пишет, он любит смотреть баскетбол✌️