Проверка типов с помощью PropTypes¶
Примечание:
С версии React 15.5
React.PropTypes
были вынесены в отдельный пакет. Так что используйте библиотекуprop-types
.Вы можете использовать codemod-скрипт, чтобы провести замену в коде на использование этой библиотеки.
По мере роста вашего приложения вы можете отловить много ошибок с помощью проверки типов. Для этого можно использовать расширения JavaScript вроде Flow и TypeScript. Но, даже если вы ими не пользуетесь, React предоставляет встроенные возможности для проверки типов. Для запуска этой проверки на пропсах компонента вам нужно использовать специальное свойство propTypes
:
import PropTypes from 'prop-types'
class Greeting extends React.Component {
render() {
return <h1>Привет, {this.props.name}</h1>
}
}
Greeting.propTypes = {
name: PropTypes.string,
}
PropTypes
предоставляет ряд валидаторов, которые могут использоваться для проверки, что получаемые данные корректны. В примере мы использовали PropTypes.string
. Когда какой-то проп имеет некорректное значение, в консоли будет выведено предупреждение. По соображениям производительности propTypes
проверяются только в режиме разработки.
PropTypes¶
Пример использования возможных валидаторов:
import PropTypes from 'prop-types'
MyComponent.propTypes = {
// Можно объявить проп на соответствие определённому JS-типу.
// По умолчанию это не обязательно.
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
// Все, что может быть отрендерено:
// числа, строки, элементы или массивы
// (или фрагменты) содержащие эти типы
optionalNode: PropTypes.node,
// React-элемент
optionalElement: PropTypes.element,
// Можно указать, что проп должен быть экземпляром класса
// Для этого используется оператор `instanceof`.
optionalMessage: PropTypes.instanceOf(Message),
// Вы можете задать ограничение конкретными значениями
// при помощи перечисления
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
// Объект, одного из нескольких типов
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message),
]),
// Массив объектов конкретного типа
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// Объект со свойствами конкретного типа
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
// Объект с определённой структурой
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number,
}),
// Можно добавить`isRequired` к любому из приведённому выше типу,
// чтобы показывать предупреждение,
// если проп не передан
requiredFunc: PropTypes.func.isRequired,
// Значение любого типа
requiredAny: PropTypes.any.isRequired,
// Можно добавить собственный валидатор.
// Он должен возвращать объект `Error` при ошибке валидации.
// Не используйте `console.warn` или `throw`
// - это не будет работать внутри `oneOfType`
customProp: function (props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(
'Проп `' +
propName +
'` компонента' +
' `' +
componentName +
'` имеет неправильное значение'
)
}
},
// Можно задать свой валидатор для `arrayOf` и `objectOf`.
// Он должен возвращать объект Error при ошибке валидации.
// Валидатор будет вызван для каждого элемента в массиве
// или для каждого свойства объекта.
// Первые два параметра валидатора
// - это массив или объект и ключ текущего элемента
customArrayProp: PropTypes.arrayOf(function (
propValue,
key,
componentName,
location,
propFullName
) {
if (!/matchme/.test(propValue[key])) {
return new Error(
'Проп `' +
propFullName +
'` компонента' +
' `' +
componentName +
'` имеет неправильное значение'
)
}
}),
}
Ограничение на один дочерний компонент¶
С помощью PropTypes.element
вы можете указать, что в качестве дочернего может быть передан только один элемент.
import PropTypes from 'prop-types'
class MyComponent extends React.Component {
render() {
// Это должен быть ровно один элемент.
// Иначе вы увидите предупреждение
const children = this.props.children
return <div>{children}</div>
}
}
MyComponent.propTypes = {
children: PropTypes.element.isRequired,
}
Значения пропсов по умолчанию¶
Вы можете задать значения по умолчанию для ваших props
с помощью специального свойства defaultProps
:
class Greeting extends React.Component {
render() {
return <h1>Привет, {this.props.name}</h1>
}
}
// Задание значений по умолчанию для пропсов:
Greeting.defaultProps = {
name: 'Незнакомец',
}
// Отрендерит "Привет, Незнакомец":
ReactDOM.render(
<Greeting />,
document.getElementById('example')
)
Если вы используете один из Babel-плагинов по преобразованию кода, вроде transform-class-properties, то можете объявить defaultProps
как статическое свойство класса (для компонента-наследника от React.Component
). Этот синтаксис ещё не утверждён, так что для его работы в браузере нужна компиляция. Подробнее смотрите в предложении о полях класса.
class Greeting extends React.Component {
static defaultProps = {
name: 'незнакомец',
}
render() {
return <div>Привет, {this.props.name}</div>
}
}
Определение defaultProps
гарантирует, что this.props.name
будет иметь значение, даже если оно не было указано родительским компонентом. Сначала применяются значения по умолчанию, заданные в defaultProps
. После запускается проверка типов с помощью propTypes
. Так что проверка типов распространяется и на значения по умолчанию.