React.js: делаем код чище с централизованными PropTypes
Как сократить самоповторы и сделать код чище, синхронизировать серверный код и централизировать PropTypes при использовании React.js?
Существует 3 популярных подхода для работы с типами в React: PropType, TypeScript и Flow.
Поскольку первый подход предоставляет предупреждения о типах во время запуска, полезно быть как можно более конкретным.
- Компонент принимает объект? Объявите форму объекта.
- Prop принимает определенный список значений? Используйте oneOf.
- Массив должен содержать числа? Используйте arrayOf.
- Можно объявлять собственные типы.
Пример PropType:
UserDetails.propTypes = { user: PropTypes.shape({ id: PropTypes.number.isRequired, firstName: PropTypes.string.isRequired, lastName: PropTypes.string.isRequired, role: PropTypes.oneOf(['user','admin']) };
В существующих приложениях с большими объектами, это быстро приведет к большому количеству кода. Это проблема, так как в Реакте часто нужно передавать один и тот же объект множеству компонентов. Повторение этого процесса во множестве компонентов нарушает принцип DRY (Don’t Repeat Yourself). Самоповторы приводят к проблемам с поддержкой.
Как централизовать PropTypes
Централизовать типы можно в ‘/types/index.js’.
// types/index.js import { shape, number, string, oneOf } from 'prop-types'; export const userType = shape({ id: number, firstName: string.isRequired, lastName: string.isRequired, company: string, role: oneOf(['user', 'author']), address: shape({ id: number.isRequired, street: string.isRequired, street2: string, city: string.isRequired, state: string.isRequired, postal: number.isRequired }); });
Для сокращения объявлений на второй строке используются именованные импорты.
И вот как можно использовать уже объявленные типы:
import React from 'react'; import {userType} from './types'; function User({ user }) { return ( <div> <h1>{user.firstName} {user.lastName}</h1> </div> ) } User.propTypes = { user: userType.isRequired }; export default User;
Использование именованных импортов дает возможность отсылаться к экспортированному PropType, объявленному на второй строке. Он используется на строке 13.
Преимущества этого подхода:
- Централизованные типы существенно упрощают их объявление в компоненте. Строка 13 отсылает к централизованному PropType, код легко читается.
- Централизованные типы просто объявляют форму, их можно отмечать как обязательные.
- Нет необходимости в копипасте. Если форма объекта меняется позже, внести изменения нужно только в одном месте.
Попробуйте написать код, который будет генерировать ваши собственные типы на сервере. Для примера, если API написано на строго типизированном языке, вроде C# или Java, попробуйте генерировать объявления PropType как часть процесса сборки серверного API, читая форму серверных классов. Таким образом, не придется волноваться о сохранении PropType на клиенте и серверный код будет синхронизирован.
Резюмируя
- Объявление типов происходит настолько явно, насколько это возможно, поиск ошибки не занимает много времени.
- Централизация типов помогает избегать самоповторов.
- При работе со строго типизированными языками на сервере рассмотрите возможность генерации типов, читая серверный код. Это обеспечит совпадение типов на сервере и клиенте.