You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.4 KiB
172 lines
5.4 KiB
8 years ago
|
---
|
||
|
id: typechecking-with-proptypes
|
||
|
title: Typechecking With PropTypes
|
||
|
permalink: docs/typechecking-with-proptypes.html
|
||
8 years ago
|
redirect_from:
|
||
|
- "docs/react-api.html#typechecking-with-proptypes"
|
||
8 years ago
|
---
|
||
|
|
||
8 years ago
|
> Note:
|
||
8 years ago
|
>
|
||
|
> `React.PropTypes` has moved into a different package since React v15.5. Please use [the `prop-types` library instead](https://www.npmjs.com/package/prop-types).
|
||
|
>
|
||
7 years ago
|
>We provide [a codemod script](/blog/2017/04/07/react-v15.5.0.html#migrating-from-react.proptypes) to automate the conversion.
|
||
8 years ago
|
|
||
8 years ago
|
As your app grows, you can catch a lot of bugs with typechecking. For some applications, you can use JavaScript extensions like [Flow](https://flowtype.org/) or [TypeScript](https://www.typescriptlang.org/) to typecheck your whole application. But even if you don't use those, React has some built-in typechecking abilities. To run typechecking on the props for a component, you can assign the special `propTypes` property:
|
||
|
|
||
|
```javascript
|
||
8 years ago
|
import PropTypes from 'prop-types';
|
||
|
|
||
8 years ago
|
class Greeting extends React.Component {
|
||
|
render() {
|
||
|
return (
|
||
|
<h1>Hello, {this.props.name}</h1>
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Greeting.propTypes = {
|
||
8 years ago
|
name: PropTypes.string
|
||
8 years ago
|
};
|
||
|
```
|
||
|
|
||
8 years ago
|
`PropTypes` exports a range of validators that can be used to make sure the data you receive is valid. In this example, we're using `PropTypes.string`. When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. For performance reasons, `propTypes` is only checked in development mode.
|
||
8 years ago
|
|
||
8 years ago
|
### PropTypes
|
||
8 years ago
|
|
||
|
Here is an example documenting the different validators provided:
|
||
|
|
||
|
```javascript
|
||
8 years ago
|
import PropTypes from 'prop-types';
|
||
|
|
||
8 years ago
|
MyComponent.propTypes = {
|
||
|
// You can declare that a prop is a specific JS primitive. By default, these
|
||
|
// are all optional.
|
||
8 years ago
|
optionalArray: PropTypes.array,
|
||
|
optionalBool: PropTypes.bool,
|
||
|
optionalFunc: PropTypes.func,
|
||
|
optionalNumber: PropTypes.number,
|
||
|
optionalObject: PropTypes.object,
|
||
|
optionalString: PropTypes.string,
|
||
|
optionalSymbol: PropTypes.symbol,
|
||
8 years ago
|
|
||
|
// Anything that can be rendered: numbers, strings, elements or an array
|
||
|
// (or fragment) containing these types.
|
||
8 years ago
|
optionalNode: PropTypes.node,
|
||
8 years ago
|
|
||
|
// A React element.
|
||
8 years ago
|
optionalElement: PropTypes.element,
|
||
8 years ago
|
|
||
|
// You can also declare that a prop is an instance of a class. This uses
|
||
|
// JS's instanceof operator.
|
||
8 years ago
|
optionalMessage: PropTypes.instanceOf(Message),
|
||
8 years ago
|
|
||
|
// You can ensure that your prop is limited to specific values by treating
|
||
|
// it as an enum.
|
||
8 years ago
|
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
|
||
8 years ago
|
|
||
|
// An object that could be one of many types
|
||
8 years ago
|
optionalUnion: PropTypes.oneOfType([
|
||
|
PropTypes.string,
|
||
|
PropTypes.number,
|
||
|
PropTypes.instanceOf(Message)
|
||
8 years ago
|
]),
|
||
|
|
||
|
// An array of a certain type
|
||
8 years ago
|
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
|
||
8 years ago
|
|
||
|
// An object with property values of a certain type
|
||
8 years ago
|
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
|
||
8 years ago
|
|
||
|
// An object taking on a particular shape
|
||
8 years ago
|
optionalObjectWithShape: PropTypes.shape({
|
||
|
color: PropTypes.string,
|
||
|
fontSize: PropTypes.number
|
||
8 years ago
|
}),
|
||
|
|
||
|
// You can chain any of the above with `isRequired` to make sure a warning
|
||
|
// is shown if the prop isn't provided.
|
||
8 years ago
|
requiredFunc: PropTypes.func.isRequired,
|
||
8 years ago
|
|
||
|
// A value of any data type
|
||
8 years ago
|
requiredAny: PropTypes.any.isRequired,
|
||
8 years ago
|
|
||
|
// You can also specify a custom validator. It should return an Error
|
||
|
// object if the validation fails. Don't `console.warn` or throw, as this
|
||
|
// won't work inside `oneOfType`.
|
||
|
customProp: function(props, propName, componentName) {
|
||
|
if (!/matchme/.test(props[propName])) {
|
||
|
return new Error(
|
||
|
'Invalid prop `' + propName + '` supplied to' +
|
||
|
' `' + componentName + '`. Validation failed.'
|
||
|
);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// You can also supply a custom validator to `arrayOf` and `objectOf`.
|
||
|
// It should return an Error object if the validation fails. The validator
|
||
|
// will be called for each key in the array or object. The first two
|
||
|
// arguments of the validator are the array or object itself, and the
|
||
|
// current item's key.
|
||
8 years ago
|
customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
|
||
8 years ago
|
if (!/matchme/.test(propValue[key])) {
|
||
|
return new Error(
|
||
|
'Invalid prop `' + propFullName + '` supplied to' +
|
||
|
' `' + componentName + '`. Validation failed.'
|
||
|
);
|
||
|
}
|
||
|
})
|
||
|
};
|
||
|
```
|
||
|
|
||
8 years ago
|
### Requiring Single Child
|
||
8 years ago
|
|
||
8 years ago
|
With `PropTypes.element` you can specify that only a single child can be passed to a component as children.
|
||
8 years ago
|
|
||
|
```javascript
|
||
8 years ago
|
import PropTypes from 'prop-types';
|
||
|
|
||
8 years ago
|
class MyComponent extends React.Component {
|
||
|
render() {
|
||
|
// This must be exactly one element or it will warn.
|
||
8 years ago
|
const children = this.props.children;
|
||
8 years ago
|
return (
|
||
|
<div>
|
||
|
{children}
|
||
|
</div>
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MyComponent.propTypes = {
|
||
8 years ago
|
children: PropTypes.element.isRequired
|
||
8 years ago
|
};
|
||
|
```
|
||
|
|
||
|
### Default Prop Values
|
||
|
|
||
|
You can define default values for your `props` by assigning to the special `defaultProps` property:
|
||
|
|
||
|
```javascript
|
||
|
class Greeting extends React.Component {
|
||
|
render() {
|
||
|
return (
|
||
|
<h1>Hello, {this.props.name}</h1>
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Specifies the default values for props:
|
||
|
Greeting.defaultProps = {
|
||
|
name: 'Stranger'
|
||
|
};
|
||
|
|
||
|
// Renders "Hello, Stranger":
|
||
|
ReactDOM.render(
|
||
|
<Greeting />,
|
||
|
document.getElementById('example')
|
||
|
);
|
||
|
```
|
||
|
|
||
|
The `defaultProps` will be used to ensure that `this.props.name` will have a value if it was not specified by the parent component. The `propTypes` typechecking happens after `defaultProps` are resolved, so typechecking will also apply to the `defaultProps`.
|