Weakly typed languages such as JavaScript make programming easy. You do not need to go digging through documentation to understand every type in your dependencies, especially when coding in an IDE. While this feature can be useful, it can become a burden for you and your team as the number of variables grows and old developers leave your projects.
Type checking in React through the prop-types package ensures that you know what each variable stores even if documentation is lacking or not helpful. In this discourse, we examine prop types in depth to help you build a quality codebase.
Before getting started, make sure you have a basic understanding of React. You can import the code in this tutorial into your own application and start experimenting.
We use Node.js. You only need to include the core React libraries in your package.json
file:
"dependencies": { "react": "^17.0.1", "react-dom": "^17.0.1", "react-scripts": "4.0.0", "web-vitals": "^0.2.4" }
Make sure you have a full React and Node.js project. You are now ready to start working with prop types.
React prop types are a way to ensure that the types passed to your functions match those you intended the function to take. Prop types keep you from making an inappropriate method call, particularly when combined with unit testing.
It is not uncommon to find a function in your code, long after writing it, and realize that it does not quite match what you need. For example, if a method reliably returns a string-based ISO timestamp and you are performing math on numeric UTC timestamps, the result is a pesky undefined value at some point after your function call.
Under the hood, React checks the property types passed to a component against those you define. The framework logs a warning to the console when they do not match.
Since the function only logs a warning, make sure to check your console before pushing to production. Otherwise, you may miss a conflict.
Weakly typed languages do not require you to specify the types associated with different variables — JavaScript does not check your variables. They’re different from strongly typed server-side languages, in that errors fatally break programs at runtime, creating a headache for users and developers alike.
Consider the following React components:
import PropTypes from 'prop-types'; // Class-based component class CustomComponent extends React.Component { static defaultProps = { mystring: "Hello", appid: "App-1" } constructor(props) { super(); this.myString = props.message; } render() { return ( <div> {this.myString} {this.props.appid} </div>) } } // Functional component const Addition = (props) => { console.log(props); const outputNum = props.mynum + props.mynum; return ( <div> Answer: {outputNum} </div>) };
There are multiple variables and properties you must set. The myString
variable is a string, mynum
is a number, and appid
is a string-based unique identifier for the application.
If you pass mynum
as a string, the component fails to render, creating a potentially serious issue. Type checking lets you find these problems early by alerting you to inappropriately set properties.
Type checking in React through prop types requires creating a separate object containing metadata regarding your properties. The PropTypes
module contains a number of property types matching those available in JavaScript.
Add the following in the same file as your components to verify that the properties you pass are correct:
Addition.propTypes = { mynum: PropTypes.number } CustomComponent.propTypes = { mystring: PropTypes.string, appid: PropTypes.string }
This object ensures that mynum
is a number. It also ensures that appid
and mystring
are strings. The program logs to the console when they are not.
React is a JavaScript library. The available property types are the same as those in JavaScript.
Available types, matching with their JavaScript equivalents, include:
It is also possible to declare that a property is an instance of a class. Use PropTypes.instanceOf(object)
to do so.
There is an additional use for property types. Code can break when you fail to pass parameters. To avoid this, you can set default prop values throughout your code instead. However, this process becomes unwieldy as your program grows and you need to track countless numbers of variables.
The React framework lets you set meaningful defaults alongside your components. You can set appid
to “App-1” and mystring
to “Hello”:
CustomComponent.defaultProps = { mystring: "Hello", appid: "App-1" }
This feature also works with functional components:
Addition.defaultProps = { mynum: 0 }
Now, if the properties are not set, the program will not fail to render. Instead, the values match those you set.
If using Babel transforms, you can write cleaner code when setting defaults. Instead of using a separate object, incorporate them directly in the target component. Babel transforms your code into the appropriate format.
Our default component becomes:
// Class-based component class CustomComponent extends React.Component { static defaultProps = { mystring: "Hello", appid: "App-1" } constructor(props) { super(); this.myString = props.message; } render() { return ( <div> {this.myString} {this.props.appid} </div>) } }
There is no need to look through larger JavaScript files to find defaults. They are directly in the attached object. There is a nominal impact on compile time for your code. However, users will not notice the difference.
Setting defaults is not always the best practice. There are cases where you want to check if a value is not provided and set your rendered content appropriately. Instead of providing mynum
with a default value, you can check for an undefined
value and set an alert.
Using these values works best when there is a logical default matching the type you set. This is ideal for appid
or mystring
. Setting them renders a complete message even if you do not provide values.
While React logs issues to the console, and you will want to test components before pushing to production, it is possible to monitor issues in production as well. Application Performance Management (APM) tools capture issues and information sent to the console, pushing them to a centralized location.
In this way, property types serve as a powerful way to catch bugs that unknowingly reach your development or production environments. Stay on top of your APM after every release.
While the weak typing of JavaScript can help you push applications quickly, the original intent of a function can be lost as your codebase grows. Checking property types and logging conflicts to an accessible location gives your team the knowledge to use your codebase without reading more code or searching through documentation.
Here, we discussed how to tackle this issue using prop types in React. We also looked at how to create default values that can help avoid undefined variables from becoming a major issue.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]