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