3.2 Проверка типов с PropTypes
Разработчики предоставляют скрипт codemode для автоматизации преобразования.
С ростом вашего приложения, вы можете получить много багов с проверками типов.
Для некоторых приложений вы можете использовать JavaScript расширения, такие как
Flow
или
TypeScript
, чтобы проверять типы во всем вашем приложении. Но даже если
вы их не используете, React имеет несколько встроенных возможностей по проверке типов.
Чтобы запустить проверку типов для свойств компонента, вы можете назначить специальное
свойство propTypes
:
import PropTypes from 'prop-types';
class HelloWorld extends React.Component {
render() {
return (
<h1>Привет, {this.props.name}</h1>
);
}
}
HelloWorld.propTypes = {
name: PropTypes.string
};
PropTypes
экспортирует множество валидаторов, которые могут использоваться,
чтобы убедиться, что данные, которые вы получаете, являются валидными.
В данном примере мы используем PropTypes.string
. Когда свойству предоставляется
не валидное значение, будет показано предупреждение в JavaScript консоли.
По соображениям производительности, propTypes
работает только в режиме разработки.
Здесь показан пример, который отображает различные предоставленные валидаторы:
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// Вы можете объявить, что свойство является определенным JS примитивом.
// По умолчанию они все необязательны.
myOptionalArray: PropTypes.array,
myOptionalBool: PropTypes.bool,
myOptionalFunc: PropTypes.func,
myOptionalNumber: PropTypes.number,
myOptionalObject: PropTypes.object,
myOptionalString: PropTypes.string,
myOptionalSymbol: PropTypes.symbol,
// Все, что может быть отрисовано: числа, строки, элементы или массив
// (или фрагмент), содержащий эти типы
myOptionalNode: PropTypes.node,
// React-элемент.
myOptionalElement: PropTypes.element,
// Вы также можете обьявить, что свойство является экземпляром класса.
// Для этого используется instanceof оператор.
myOptionalMessage: PropTypes.instanceOf(Message),
// Вы можете гарантировать, что ваше свойство ограничено определенным
// набором значений, представленных перечислением
myOptionalEnum: PropTypes.oneOf(['News', 'Photos']),
// Объект, который может иметь один из перечисленых типов
myOptionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// Массив объектов определенного типа
myOptionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// Объект со значениями свойств определенного типа
myOptionalObjectOf: PropTypes.objectOf(PropTypes.number),
// Объект, приобретающий определенную форму
myOptionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
}),
// Вы можете связать любой из вышеперечисленых валидаторов с 'isRequired', чтобы убедиться,
// что предупреждение показывается, если значение свойства не предоставлено
myRequiredFunc: PropTypes.func.isRequired,
// Значение произвольного типа данных
myRequiredAny: 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 объект, если валидация проходит с ошибкой.
// Валидатор будет вызван для каждого ключа в массиве или объекте.
// Первые два аргумента валидатора являются сам массив или объект, и текущий ключ элемента
myCustomArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
return new Error(
'Invalid prop `' + propFullName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
})
};
Используя PropTypes.element
вы можете указать, что только один потомок
может быть передан в компонент как children
.
import PropTypes from 'prop-types';
class CustomComponent extends React.Component {
render() {
// Это должен быть в точности один элемент, иначе будет предупреждение
const children = this.props.children;
return (<div>{children}</div>);
}
}
CustomComponent.propTypes = {
children: PropTypes.element.isRequired
};
Вы можете определять значения по умолчанию для ваших свойств,
используя специальное свойство defaultProps
:
class HelloWorld extends React.Component {
render() {
return (<p>Привет, {this.props.name}!</p>);
}
}
// Определяет значения свойств по умолчанию
HelloWorld.defaultProps = {
name: 'Вася'
};
// Отрисует "Привет, Вася!":
ReactDOM.render(<HelloWorld />, document.getElementById('example'));
Если вы используете преобразование Babel, такое как transform-class-properties
, вы также можете
объявлять defaultProps
как статическое свойство в классе React-компонента. Этот синтаксис еще не
окончателен, и для его работы в браузере потребуется выполнить этап компиляции. Для получения
дополнительной информации см.
.
class HelloWorld extends React.Component {
static defaultProps = {
name: 'Вася'
}
render() {
return (<p>Привет, {this.props.name}!</p>);
}
}
Свойство defaultProps
будет использовано, чтобы гарантировать, что свойство
this.props.name
, будет иметь значение, если оно не было указано родительским
компонентом. Проверка типов propTypes
происходит после отработки defaultProps
,
поэтому проверка типов будет также применена и к defaultProps
.