PropTypes: Your tool for good props transfer.

PropTypes: Your tool for good props transfer.

PropTypes is a helpful tool for ensuring that the data passed between React components are of the correct type. Most of the time we forget to specify which kind/type of data a variable will contain and that carelessness brings bugs and improper results.

Intro:

Hello Friends, Rahul this side with my friend Chubby πŸ™‹πŸ½β€β™‚οΈ, are going to discuss Props and their use in ReactJS and how we can make React components bug-free from props. This will be our first blog on React topics.

According to @Sloba PropType is like a Bouncer who checks the IDs of visitors before letting them in. Just as a Bouncer, verifies that each person is of legal age and has a valid ID type. Checking verifies that the data we are passing to our component has correct data types and properties and just like how a bouncer helps ensure a safe and enjoyable experience for everyone at the nightclub. Type tracking by PropTypes can help prevent bugs and improves the overall quality and maintainability of our code.

Have you encountered the above problem on vs-code? Yes! I have πŸ™‹πŸ½β€β™‚οΈ.

What this problem says? 'handleClick' is missing in props validation. What!! 🀯

If we see what the eslint suggests us to see...

It suggests either we disallow the missing props validation or give the validation by defining their data types by using PropTypes. With a single line of comment, i.e., /* eslint-disable react/prop-types */ will remove the most important definition for the props in order to make them independent of their own type.

What is the real problem?

// lets consider a simple Car component model which gives us the instance of the car and through props we can modify its specifications.
import React from 'react';
// other imports

const Car = (props) {
    return (
        <>
            <h2> Car: {props.name} </h2>
            <h4> Company: {props.company} </h4>
            <h6> Build: {props.year} </h6>
            <br/>
            <strong> Price: {props.price} </strong>
        </>        
    );
};
export default Car;

In the above example, we have different types of props which we are passing to the CarComponent and can have different types of data-type. We have not defined what type of data these props should contain. It will render even if we pass a string to the price prop and a number to the car name (by mistake). And it will affect the output and create bugs.

Why do we need to define props?

πŸ™‹πŸ½β€β™‚οΈHey Rahul, Why do we need to define the data type of the props if we have already declared it in the target component where these props gonna used?

Nice Question Chubby!, Since in small projects where we do not have huge component folders with other container components, we do not require PropType type-checking as it is not expected that developer misses any prop to pass as the wrong type. But mistakes are inevitable. To ensure we pass on exact data with its proper data-type so that we can make our development cycle smooth.

PropType: How to use it?

PropType is an object containing properties that should be defined in the component before passing those properties to another component. It describes the expected data types and properties of the props object that the component receives.

It's not included with React anymore and you can install it via npm. npm i prop-types

import React from 'react';
// other imports
//Todo: 1 Import PropType
import PropTypes from 'prop-types';

const Car = (props) {
    return (
        <>
            <h2> Car: {props.name} </h2>
            <h4> Company: {props.company} </h4>
            <h6> Build: {props.year} </h6>
            <br/>
            <strong> Price: {props.price} </strong>
        </>        
    );
};
//Todo: 2 add propType object to the Car component.
Car.propType ={
    name = PropTypes.string.isRequired,
    campany = PropTypes.string.isRequired,
    year = PropTypes.instanceOf(Date),
    price = PropTypes.number.isRequired
}
export default Car;

So, if the incorrect prop-type is given or missed any prop to pass, will show a warning message. If we pass price='30000', in the Home component, we'll get an error on the console : Failed prop type: Invalid prop 'price' of type 'string' supplied to 'Car', expected 'number' . With isRequired modifier, we specify that the prop is important to pass on and should show an error if missing.

If the props come inside an object like:

import PropTypes from 'prop-types';

const Car = ({carDetail}) {
// we desturcture the prop to ge the carDetail object which contain the props and this object have the definite shape/size(which we have to prevent).
    return (
        <>
            <h2> Car: {carDetail.name} </h2>
            <h4> Company: {carDetail.company} </h4>
            <h6> Build: {carDetail.year} </h6>
            <br/>
            <strong> Price: {carDetail.price} </strong>
        </>        
    );
};
//Todo: 2 add PropType object to the Car component.
Car.propType ={
    carDetails: PropTypes.arrayOf(
        PropTypes.shape({
            name = PropTypes.string.isRequired,
            campany = PropTypes.string.isRequired,
            year = PropTypes.instanceOf(Date),
            price = PropTypes.number.isRequired
        })
    ).isRequired
}
export default Car;

Again, let's consider a real-life example, a custom Button component that we can create to make different types of buttons.

import React from 'react';

const CustomButton = ({ type, title, customStyle, handleClick}) => {
    return (
        <button 
            className={`${customStyle} px-2 rounded-lg`}
            type={type}
            onClick={handleClick}
        >
            {title}</button>
    );
};
export default CustomButton;
// This CustomButton we use in our Payment page where this button will trigger the payment gateway. 

// PaymentComponent
import React from 'react';
// other imports

const Payment = () => {
    const paymentHandler = () => {} // payment logic
    return (
        <NavBar />
        <MainContent />
        <CustomButton 
             type='submit' 
             title='proceed to Pay'
             customStyle='p-4 bg-blue-400 underline'
             handleClick={paymentHandler}
        />   
    );
};
export default Payment;
// So here we have to define the data-types of the props by passing the propType object on the Payment Component.
Payment.propType{
    type= PropTypes.string.isRequired,
    title= PropTypes.string.isRequired,
    customStyle= PropTypes.string.isRequired,
    handleClick = PropTypes.func.isRequired,
}
// don't forget to import PropTypes.

Here, in CustomButton, if we destructure the props so that we anticipate what props we are expecting or are required to use in the custom button in order to make it custom. Through destructuring also we can negate the possibility of error in prop drilling.

Prop Drilling: is a technique of passing props from one component to another. The component can be of the same branch(parent-child) or of a different branch which is connected only through the root component.

So we encounter the problem in CustomButton related to these props missing validation. We have to validate the props before passing them to the CustomButton so that when it stores the data of the props it verifies its data-type and alerts us if we give the wrong data-type or missed using any prop in the child component.

Types of PropTypes

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.arrayOf,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

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

There are other propTypes also, checkout on https://legacy.reactjs.org/docs/typechecking-with-proptypes.html
Also Since propType is going to diminish as it is more likely to indicate developers to adopt TypeScript which is a strict way of writing JS. Hence props and contexts were defined in a strict mode which improves the code maintainability and scalability.

Also Checkout @sloba on Youtube.

Outro:

I know It was a much-delayed blog. Because of my job hunting, I am currently packed with learning and project development. However, I'll try to post at least two posts in a month. Please bear with me. Check out my GitHub where I am more frequently posting new projects. You can send a connection request on LinkedIn where I am now going to post this blog to promote this.

πŸ™‹πŸ½β€β™‚οΈ What about programming memes??

Oh yes! Sorry πŸ˜ͺ

Β