Crash Course on props-types
Tags: react, javascript, webdev, typescript
Published: 2023-12-04 11:36:31

### 01. What are prop-types?
PropTypes are used to validate props in React. 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.

### 02. How to use prop-types?

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

ComponentName.propTypes = {
  name: PropTypes.string,
};
```


### 03. Most Common PropTypes

```javascript
ComponentName.propTypes = {
  optionalArray: PropTypes.array, // Array
  optionalBool: PropTypes.bool, // Boolean
  optionalFunc: PropTypes.func, // Function
  optionalNumber: PropTypes.number, // Number
  optionalObject: PropTypes.object, // Object 
  optionalString: PropTypes.string, // String 
  optionalSymbol: PropTypes.symbol, // Symbol
}
```

### 04. What is PropTypes.node?

PropTypes.node is used to validate a single child element or a fragment.

```javascript
ComponentName.propTypes = {
  optionalNode: PropTypes.node,
}
```
Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.children}</div>;
}

ComponentName.propTypes = {
  children: PropTypes.node, // Anything that can be rendered.
};

<ComponentName>Hello World</ComponentName>; // Valid
<ComponentName><h1>Hello World</h1></ComponentName>; // Valid
```

### 05. What is PropTypes.element?

PropTypes.element is used to validate a single child element.

```javascript
ComponentName.propTypes = {
  optionalElement: PropTypes.element,
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.element,
};

<ComponentName message={<h1>Hello World</h1>} />; // Valid
<ComponentName message="Hello World" />; // Invalid
<ComponentName message={(
    <>
      <h1>Hello</h1>
      <h2>World</h2>
    </>
  )} 
/>; // Valid
```

### 06. What is PropTypes.elementType?

PropTypes.elementType is used to validate a single child element or a function that returns a child element.

```javascript
ComponentName.propTypes = {
  optionalElementType: PropTypes.elementType,
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.elementType,
};

<ComponentName message={<h1>Hello World</h1>} />; // Valid
<ComponentName message="Hello World" />; // Invalid
<ComponentName message={(
    <>
      <h1>Hello</h1>
      <h2>World</h2>
    </>
  )}
/>; // Valid
```



### 07. What is PropTypes.instanceOf?

PropTypes.instanceOf is used to validate that the prop is an instance of a class.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.instanceOf(Message),
}
```

Use Cases:

```javascript
class Message {}

function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.instanceOf(Message),
};

<ComponentName message={new Message()} />; // Valid
<ComponentName message="Hello World" />; // Invalid
```

### 08. What is PropTypes.oneOf?

PropTypes.oneOf is used to validate that the prop is one of the values in an array.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.oneOf(["News", "Photos"]),
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.oneOf(["News", "Photos"]),
};

<ComponentName message="News" />; // Valid
<ComponentName message="Photos" />; // Valid
<ComponentName message="Hello World" />; // Invalid
```

### 09. What is PropTypes.oneOfType?

PropTypes.oneOfType is used to validate that the prop is one of the values in an array of types.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
  ]),
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
  ]),
};

<ComponentName message="Hello World" />; // Valid
<ComponentName message={123} />; // Valid
<ComponentName message={true} />; // Invalid
```

### 10. What is PropTypes.arrayOf?

PropTypes.arrayOf is used to validate that the prop is an array of a certain type.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.arrayOf(PropTypes.string),
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.arrayOf(PropTypes.string),
};

<ComponentName message={["Hello", "World"]} />; // Valid
<ComponentName message={["Hello", 123]} />; // Invalid
```

### 11. What is PropTypes.objectOf?

PropTypes.objectOf is used to validate that the prop is an object with property values of a certain type.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.objectOf(PropTypes.string),
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.objectOf(PropTypes.string),
};

<ComponentName message={{ hello: "Hello", world: "World" }} />; // Valid
<ComponentName message={{ hello: "Hello", world: 123 }} />; // Invalid
```

### 12. What is PropTypes.shape?

PropTypes.shape is used to validate that the prop is an object taking on a particular shape. It is different from PropTypes.exact in that it does not warn you about extra properties.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number,
  }),
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number,
  }),
};

<ComponentName message={{ color: "red", fontSize: 12 }} />; // Valid
<ComponentName message={{ color: "red", fontSize: "12px" }} />; // Invalid
```

### 13. What is PropTypes.exact?

PropTypes.exact is used to validate that the prop is an object taking on a particular shape, with no extra properties.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.exact({
    color: PropTypes.string,
    fontSize: PropTypes.number,
  }),
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.exact({
    color: PropTypes.string,
    fontSize: PropTypes.number,
  }),
};

<ComponentName message={{ color: "red", fontSize: 12 }} />; // Valid
<ComponentName message={{ color: "red", fontSize: "12px" }} />; // Invalid
<ComponentName message={{ color: "red", fontSize: 12, extra: true }} />; // Invalid
```

### 14. What is PropTypes.any?

PropTypes.any is used to validate that the prop can be any data type.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.any,
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.any,
};

<ComponentName message="Hello World" />; // Valid
<ComponentName message={123} />; // Valid
<ComponentName message={true} />; // Valid
```

### 15. What is PropTypes.[some_type].isRequired?

PropTypes.[some_type].isRequired is used to validate that the prop is required.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.string.isRequired,
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

ComponentName.propTypes = {
  message: PropTypes.string.isRequired,
};

<ComponentName message="Hello World" />; // Valid
<ComponentName />; // Invalid
```

### 16. What is PropTypes.custom?

PropTypes.custom is used to validate that the prop is validated by a custom validator function.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.string,
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.message}</div>;
}

function customPropType(props, propName, componentName) {
  if (!/matchme/.test(props[propName])) {
    return new Error(
      "Invalid prop `" +
        propName +
        "` supplied to" +
        " `" +
        componentName +
        "`. Validation failed."
    );
  }
}

// if type is set to string
ComponentName.propTypes = {
  message: PropTypes.string,
};

<ComponentName message="matchme" />; // Valid
<ComponentName message="nomatch" />; // Invalid

// if type is set to customPropType
ComponentName.propTypes = {
  message: customPropType,
};

<ComponentName message="matchme" />; // Valid
<ComponentName message="nomatch" />; // Invalid
```

### 17. What is PropTypes.arrayOf(PropTypes.shape())?

PropTypes.arrayOf(PropTypes.shape()) is used to validate that the prop is an array of objects taking on a particular shape.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.arrayOf(
    PropTypes.shape({
      color: PropTypes.string,
      fontSize: PropTypes.number,
    })
  ),
}
```

Use Cases:

```javascript
function ComponentName(props) {
  return <div>{props.messages}</div>;
}

ComponentName.propTypes = {
  messages: PropTypes.arrayOf(
    PropTypes.shape({
      color: PropTypes.string,
      fontSize: PropTypes.number,
    })
  ),
};

<ComponentName
  messages={[
    { color: "red", fontSize: 12 },
    { color: "green", fontSize: 14 },
  ]}
/>; // Valid
<ComponentName
  messages={[
    { color: "red", fontSize: 12 },
    { color: "green", fontSize: "14px" },
  ]}
/>; // Invalid
```

### 18. What is PropTypes.arrayOf(PropTypes.oneOfType())?

PropTypes.arrayOf(PropTypes.oneOfType()) is used to validate that the prop is an array of a certain type or an array of objects taking on a particular shape.

```javascript
ComponentName.propTypes = {
  optionalMessage: PropTypes.arrayOf(
    PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.shape({
        color: PropTypes.string,
        fontSize: PropTypes.number,
      }),
    ])
  ),
}
```