We have seen how props works in React. They provide a mechanism to pass state, functions or any other information to the component tree.
defaultProps
With props, there is always a possibility that the values which are required by the component are missing or there are times when certain objects are expected to have additional details which others may not have, (ex., book description, as not all books will have description). In such cases, to prevent errors, we can use defaultProps with that component.
propTypes
On the other hand, propTypes define a strict type structure for expected props.
There is no need to install any additional package if you are using create-react-app, otherwise you need to install prop-types library.
propTypes needs to be set per component, by importing it first and later setting up actual properties by defining expected props with types and required attributes.
We will leverage our example of BookLibrary to discuss about defaultProps and PropTypes.
Using defaultProps
defaultProps works with both functional and class components. Note that the defaultProps need to be setup globally outside component scope.
For rendering books, we are creating a default object, which will have similar properties as expected props, initialized with some default values.
Whenever the props are without any properties required by the component, these properties of defaultProps are used to complete the render.
Setup
const books = [
{
id: 1,
title: "Life's Amazing Secrets",
//notice author, coverImage properties are missing from this object
},
{
id: 3,
title: "The Alchemist",
author: "Paulo Cohlo",
coverImage:
"./images/the-alchemist.jpg",
},
{
id: 4,
//notice cover image is missing from this object
title: "Grandma's Bag of Stories",
author: "Sudha Murthy",
},
];
//defaultProps object
const defaultPurchasedBook = {
id: 0,
title: "Life's Amazing Secrets",
author: "Gaur Gopal Das",
coverImage:
"./images/lifes-amazing-secrets.jpg",
};
BookDetails.defaultProps = defaultPurchasedBook;
Output
Notice how title, author for the first book and cover-Image for the last book are rendered with default values, where their original values were missing.
propTypes
Similar to defaultProps, as discussed earlier, propTypes works with both functional and class components. Note that the propTypes need to be setup globally outside component scope similar to defaultProps.
By using propTypes, one can know the type of the properties to expect from the props. To use propTypes, we need import it from "prop-types" as its part of a different library as mentioned above.
We can define in the propTypes if its required by using isRequired property, which can be assigned to every property within the propTypes object. Whenever the props which are sent whose type is not matching as per the setup in the propTypes, it will raise a console error.
To test propTypes, we are disabling the defaultProps we did set earlier.
Setup
BookDetails.propTypes = {
id: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
author: PropTypes.string.isRequired,
coverImage: PropTypes.string.isRequired,
};
Output
Notice the errors logged in the console, for each property whose type does not match or is missing.
JS Code
import PropTypes from "prop-types";
//Parent
export const BookLibrary = () => {
const books = [
{
//notice id is expected as number but we are setting it as string
title: "Life's Amazing Secrets",
//notice title, author are missing from this object
},
{
id: 3,
title: "The Alchemist",
author: "Paulo Cohlo",
coverImage:
"./images/the-alchemist.jpg",
},
{
id: 4,
//notice cover image is missing from this object
title: "Grandma's Bag of Stories",
author: "Sudha Murthy",
},
];
const [purchasedBooks, setPurchasedBooks] = useState(books);
return (
<>
<div className="container">
<div className="row">
<section className="booklist">
<div className="card-deck">
{purchasedBooks.map((book) => (
<BookDetails id={book.id} {...book} />
))}
</div>
</section>
</div>
</div>
</>
);
};
const BookDetails = ({ coverImage, title, author, id }) => {
return (
<div key={id} className="card" style={{ width: "10rem" }}>
<img className="card-img-top" src={coverImage} alt="Card image cap"></img>
<div className="card-body">
<h5 className="card-title">{title}</h5>
<h6 className="card-text">{author}</h6>
</div>
</div>
);
};
//global objects
//defaultProps object
const defaultPurchasedBook = {
id: 0,
title: "Life's Amazing Secrets",
author: "Gaur Gopal Das",
coverImage:
"./images/lifes-amazing-secrets.jpg",
};
BookDetails.defaultProps = defaultPurchasedBook;
//Prop Types
BookDetails.propTypes = {
id: PropTypes.number.isRequired, //notice use of isRequired
title: PropTypes.string.isRequired,
author: PropTypes.string.isRequired,
coverImage: PropTypes.string.isRequired,
};
Comments
Post a Comment