PropTypes & Keys
What if, he passes 42 instead of
Enforcing
user.name
to Gravatar
component? (return <li><Gravatar email={42} />
)How to make sure people now what attributes and types to pass to a component, without having to read through all the code to guess it?
You can add
propTypes
to a component:
// **** 2-props/app.js ****
..
var Gravatar = React.createClass({
propTypes: {
email: React.PropTypes.string
}
})
Now React will give a type warning (in the browser console). This helps other developers to know how to use your component.The component still works, but in this case, the gravatars don't show up.
Unique element keys
return <li key={user.id}><Gravatar email={user.email} />..
React uses this when re-renders the component. This helps React to change as little of the DOM as possible [through the diffing algorithm].
Custom validation of attribute values
What if we wanted to ensure that the users email address actually contains an "@" symbol?
// **** 2-props/app.js ****
// 4. include validateEmail
var validateEmail = require('./validateEmail');
..
// 3. creates emailType checker (copies from original app.js)
var emailType = (props, propName, componentName) => {
warning(
// validateEmail is in another module
validateEmail(props.email),
`Invalid email '${props.email}' sent to 'Gravatar'. Check the render method of '${componentName}'.`
);
};
var Gravatar = React.createClass({
propTypes: {
// 1. ++-- changes React.PropTypes.string
// - email: React.PropTypes.string
// 2. ++++
email: emailType
},
render () {
..
}
})
propTypes are functions in React. React.PropTypes.string
is a function. emailType
thus is a function as well. The get the parameters props
, propName
, componentName
. (For some reason it warns two times when the validation doesn't pass. Doesn't know why.)
Enforcing size
validation
var Gravatar = React.createClass({
propTypes: {
email: emailType
// 1. ++++ we can also make it _required_
size: React.PropTypes.number.isRequired
},
render () {
..
}
})
Before he updates his code, he says that it would be great to have a default size
set. This can be achieved with getDefaultProps()
life cycle hook
var Gravatar = React.createClass({
propTypes: {
email: emailType
size: React.PropTypes.number.isRequired
},
// 1. ++++
getDefaultProps() {
return {
size: 36
}
},
render () {
// 2. ++-- change size
// -- var size = 36;
var size = this.props.size;
var hash = md5(this.props.email);
var url = `${GRAVATAR_URL}/${hash}?s=${size*2}`;
return <img src={url} width={size} />
}
})
Great for testing. Put the dependency in getDefaultProps
. Like dependency injection. You can pass in a stub for a test.Search for proptypes shows Reusable Components. You see a list of proptypes you can specify. Goes trough the list. There's even a shape
type (color and fontSize).It's EXTREMELY useful for cooperation with other developers. It serves as a jsdoc for the component.
- What about production? Do you leave this propTypes in?They're still there. But if it's run with a production flag, React skips them. Then webpack and browserify remove it with the "dead code elimination".
If you're testing and measuring performance, make sure you test the production build, the difference is huge.