Проверка типов с помощью 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
. Так что проверка типов распространяется и на значения по умолчанию.