Proptypes

Passing in a string instead of an array, well, everything would break. Because we're calling list.map inside of our component and obviously strings don't have a .map prototype method. This is where PropTypes come into play. PropTypes allow you to declare the "type" (string, number, function, etc) of each prop being passed to a component. Then, if a prop passed in isn't of the declared type, you'll get a warning in the console.

var React = require('react');
var PropTypes = require('prop-types'); <----- required
 
class Users extends React.Component {
  render() {
    return (
      <ul>
        {this.props.list.map(function (friend) {
          return <li>{friend}</li>
        })}
      </ul>
    )
  }
}
 
class Users extends React.Component {
  render() {
    return (
      <ul>
        {this.props.list.map(function (friend) {
          return <li>{friend}</li>
        })}
      </ul>
    )
  }
}
Users.propTypes = {
  list: PropTypes.array.isRequired
}
 
ReactDOM.render(
  <Users list="john, peter, mike">,
  document.getElementById('app')
);

PropTypes are great for finding bugs in your components but what I like most about them is their ability to add documentation to a component.
A well written component, you can look at the render method to figure out what it's going to look like and I can look at its propTypes to figure out what it needs to accept to render properly.

const React = require('react');
const ReactDOM = require('react-dom');
const PropTypes = require('prop-types');
 
require('./index.css');
 
class Header extends React.Component  {
    render() {
        return ( 
            <div>
                <h1 className="logo">{ this.props.name } logo</h1>
                <h2>Subtitle : { this.props.subtitle }</h2> // will error as propTypes says its required
            </div>
        )
    }
}
 
/* PropTypes */
Header.propTypes = {
    name: PropTypes.string.isRequired,
    subtitle: PropTypes.string.isRequired
}
 
/* Component */
class App extends React.Component {
    render() {
        return (
            <div>
                Hello World! My name is john
                <Header name={this.props.name}  /> 
            </div>
        )
    }
}
 
// <App /> <-- this invokes a component 
ReactDOM.render(
    // Pass through 2 things
    // 1. The compoenent we would like to render
    // 2. Where to
    <App name="Johns" />,
    document.getElementById('app')
);

We can even check if the array is an array of objects ie.

Users.propTypes = {
  list: PropTypes.arrayOf(PropTypes.object)
}
 
// This below render will error as we are expected an array of objects ie.
list=[{name: 'John'},{name: 'Paul'}];
 
ReactDom.render = {
  <User list={[
    'Tyler',
    'Jake'
  ]} /> // error
}

We can also use shape

Users.propTypes = {
  list: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string.isRequired,
    friend: PropTypes.bool.isRequired
  }))
}

We can also build our own! similar to Cake modal field validation

Users.propTypes = {
  list: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string.isRequired,
    friend: PropTypes.bool.isRequired
  }))
}

We can also add more than one grouped for a component

Users.propTypes = {
   list: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
    if (!/matchme/.test(propValue[key])) {
      return new Error(
        'Invalid prop `' + propFullName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  })
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License