In React, it is important to know how to pass data to reusable components to dynamically render information/data on a webpage.
In React, parent components can pass information/data to child components. This information they pass is known as props. Props can be of various data types; strings, integers, objects, functions, etc, which is why you need to validate the expected data type -- to avoid a bug that can break the application. In this article, I will explain how to validate props by using a popular npm package called prop-types.
To use props and prop-types, components must be well understood as they are the building blocks of any React application.
First, let’s look at the concept of props in React. Props is the term used for ‘properties passed into React components’ and are a way of passing data from parent to child components.
Components are reusable and nested inside other components. Components represent the User Interface (UI) and serve the same purpose as JavaScript functions.
Let’s take a look at what a component is and how it can be created:
{% code-block language="js" %}
class Book extends React.Component {
render() {
return <h2>I love reading</h2>;
}
}
{% code-block-end %}
That is all we need to create a component.
You might be wondering how components help explain the differences between props and states. To use props and states, it is crucial to understand components to make them work. Though React components are reusable, the data is not. Data is not reusable because we need to change data based on the content inside a component. Data passed between components is known as props.
Here’s how components work:
{% code-block language="js" %}
class Book extends React.Component {
render() {
return <h3>I am a {this.props.genres}!</h3>;
}
}
{% code-block-end %}
From the above example, the component receives the argument as a props object.
A React component can also have default props, so if a prop isn’t passed through, it can be added. Default props will be discussed further, later in this article.
The state determines how components render, behave and exist inside a component. A state of a component is an object that holds information about our application that can be changed. How the information is handled is different from props.
Here is an example of a state in a React component:
{% code-block language="js" %}
class Counter extends React.Component {
constructor(props) {
super(props)
this.state = {
count: 0
}
}
render() { ...
}
}
{% code-block-end %}
From the example above, the state initializes through this.state . The super() is needed if we are getting our data from props, It must be called.
It will also re-render or update our application. To change states, React has its own method, setState(). When a state changes, the component updates, outputting the new values, and setstate() method takes a parameter. You can see how this works below.
{% code-block language="js" %}
class Counter extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}
updateCount() {
this.setState((previousCount, callback) => {
return { count: previousCount.count + 1 }
});
}
render() {
return (<button
onClick={() => this.updateCount()}
>
Clicked {this.state.count} times
</button>);
}
}
{% code-block-end %}
As noted earlier, setState()updates our application. We call this.setState(previousCount, props). React merges previousCount with current state and calls render(). After that, React calls props.
Calling setState is an asynchronous operation. So, having the callback function passed in as an argument to the setState function allows us to perform some operations immediately after the setState function has been completed.
When building reusable components in React, you may want the reusable component to display different data at varying places on the webpage, hence, understanding how to pass props to the component to make it dynamic is important. For example:
{% code-block language="js" %}
import React from 'react';
class Car extends React.Component{
constructor(props){
super(props);
this.state = {
data: 'Toyota'
}
}
render(){
const {data} = this.state;
return(
<div>
<Child dataCarToBrand = {data}/>
</div>
)
}
}
class Brand extends React.Component{
constructor(props){
super(props);
this.state = {
data: this.props.dataCarToBrand
}
}
render(){
const {data} = this.state;
return(
<div>
{data}
</div>
)
}
}
export default Car;
{% code-block-end %}
From the above example, the car component passes props to the brand component. Then it can access the data from the car component via this.props
defaultProps is a property in React components. Some props in React need a fallback value in case no data was passed as a prop. This is where using defaultProps comes in handy. defaultProps allows the setting of a fallback value for a prop, just in case no data was passed. This is similar to assigning a default value to a function argument. Creating a default value for a prop is quite simple, see below for an example:
{% code-block language="js" %}
class Book extends React.Component {
render() {
return <h3>I am a lover of {this.props.genres} books/h3>;
}
Book.defaultProps = {
genres: "drama",
};
}
{% code-block-end %}
Above you can see that the genres will display “drama” when it's not set in the props argument. You can also see that the defaultProps can be defined as a property on the component class itself, to set the default props for the class. The essence of defaultProps is to set a default value for the prop argument and it will be changed when the prop property is passed.
prop-types is an npm package for checking props validation. prop-types check props to ensure validation of data types. It also ensures that components use the correct data type and pass the right data.
For example:
{% code-block language="js" %}
import PropTypes from 'prop-types';
export default function Button({
name, onClick, color, wide,
}) {
return (
<button
className={`btn ${color ? 'operatorBtn' : ''} ${wide ? 'wide' : ''}`}
type="button"
value={name
onClick={onClick}
>
{name}
</button>
);
}
Button.defaultProps = {
color: null,
wide: null,
};
Button.propTypes = {
name: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
color: PropTypes.bool,
wide: PropTypes.bool,
};
{% code-block-end %}
From the example shown above:
{% code-block language="js" %}
Button.propTypes = {
name: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
color: PropTypes.bool,
wide: PropTypes.bool,
};
{% code-block-end %}
PropTypes will ensure that when "name" is passed, it is a string, and "onClick" is a function, and "color" and "wide" are booleans. If there’s a change, there will be an error and it will be easily identified.
When using prop-types, there are a few things to note in order for it to work:
1. Install prop-types
npm i prop-types
2. Import prop-types to the file
import PropTypes from 'prop-types';
3. The capitalization must be noted
Props are data passed from a parent component to a child component, to render dynamic contents without reconstructing the entire child component. Props have made creating and using reusable components very easy in React. Props can be of various data types, hence, they need to be validated to ensure that the right data type is given as the value of the prop. This can be done with the help of an npm package, prop-types.
I hope that helped you understand props and prop-types in React. Happy coding!
Career advice, the latest coding trends and languages, and insights on how to land a remote job in tech, straight to your inbox.