Prop Types and Default Props in React
Tags: react, frontend, webdev
Published: 2023-05-03 04:02:42

## Introduction
**prop-types** is a library with which you can check the type of props in React. With **defaultProps**, we can pass default values to props. **TypeScript** is used to handle type checks and default values in large projects. But as a beginner, **prop-Types** and **defaultProps** will help you write better type-safe code.

## Why use Prop-Types?
When we declare props in our React components, there is no way to check the type of props. So, while calling the Component, if the user passes any wrong value, there is no way to handle this. To resolve this problem, we can use **prop-types**.

## How to use Prop-Types?
In projects created with the **Create-React-App**,** prop-types** was already installed. You just need to import it. Then just before the export statement, define the prop types. See the below example:
```javascript
import PropTypes from 'prop-types';

const Greeting = ({name}) => {
    return (
      <h1>Hello, {name}</h1>
    );
}

Greeting.propTypes = {
  name: PropTypes.string
};

export default Greeting;
```
Some more examples(source: [React docs](https://legacy.reactjs.org/docs/typechecking-with-proptypes.html)):

```javascript
import PropTypes from 'prop-types';

MyComponent.propTypes = {
  // You can declare that a prop is a specific JS type. By default, these
  // are all optional.
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

  // Anything that can be rendered: numbers, strings, elements or an array
  // (or fragment) containing these types.
  optionalNode: PropTypes.node,

  // A React element.
  optionalElement: PropTypes.element,

  // A React element type (ie. MyComponent).
  optionalElementType: PropTypes.elementType,

  // You can also declare that a prop is an instance of a class. This uses
  // JS's instanceof operator.
  optionalMessage: PropTypes.instanceOf(Message),

  // You can ensure that your prop is limited to specific values by treating
  // it as an enum.
  optionalEnum: PropTypes.oneOf(['News', 'Photos']),

  // An object that could be one of many types
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),

  // An array of a certain type
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

  // An object with property values of a certain type
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),

  // An object taking on a particular shape
  optionalObjectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),

  // An object with warnings on extra properties
  optionalObjectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number
  }),   

  // You can chain any of the above with `isRequired` to make sure a warning
  // is shown if the prop isn't provided.
  requiredFunc: PropTypes.func.isRequired,

  // A required value of any data type
  requiredAny: PropTypes.any.isRequired,

  // 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.
  customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
    if (!/matchme/.test(propValue[key])) {
      return new Error(
        'Invalid prop `' + propFullName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  })
};
```
## Why use Default Props?
Sometimes we do some calculations or build a UI based on props value. But what if the user fails to provide the props? Then the UI will break. To resolve this problem, **Default Props** came into the picture. 

## How to use Default Props?
Whenever we create a React component, it already has the `defaultProps` property. You need to define it before the `export` statement. Inside the `defaultProps` object, we write `prop-name` and `default value` as key-value pair. See the below example:
```javascript
const Greeting = ({name}) => {
    return (
      <h1>Hello, {name}</h1>
    );
}

Greeting.defaultProps = {
  name: 'John Doe'
};

export default Greeting;
```
## Summary
In this blog, we have discussed the **prop-types** and **defaultProps**. In modern React projects, we use **TypeScript** to ensure type safety. But if you are new to React or want to ensure type checks in your JavaScript-based React project, then **prop-types** and **defaultProps** are a great way to start.Follow me to learn more about **React** and other **Frontend Development** skills.