In this article, I will guide you through my experience building and publishing a custom React hook called "useStore". As you may know, custom hooks are useful for code reusability, component organization, and development efficiency.
The "usePersistedState" and "useSessionState" hooks were created with this in mind, and they allowed me to store variables in the browser's local storage and to provide global store functionality to my react application. These were optimized and developed for over three years and became a fundamental piece of my application. So, I decided to publish these hooks as an npm package, making them available for others.
Working with custom hooks and making them available as an npm module has some challenges that I'm going to discuss, such as:
- Thorough understanding and careful configuration of the application's needs;
- The process of creating a development environment and publishing it;
- Providing proper documentation and well-documented README files;
- Being able to offer transparency about changes made in each version.
Finally, I'll explain the functionality of my custom hook, how it works, how it was implemented, and the benefits of using custom hooks in general.
Creating and implementing custom React hooks
Custom React hooks are useful for code reusability, improving component organization, and improving development efficiency. My journey using them started while working on a Disney project and needing a solution for handling state and global variables without spending time implementing Redux, as it was time-consuming and not the best tool for the application. From this need, I created the "usePersistedState" and "useSessionState" hooks, which allowed me to store variables in the browser's local storage, allowing me to access them globally within the app.
Implementing a custom React hook allowed our development team to easily access and save data on the local storage or session storage from anywhere within the application (root components, child components, utils, etc.). The hook works similarly to the useState hook, returning an array with a getter and a setter. It creates a key in the storage and saves data as a stringified object. It also supports JSON objects and other data types.
The local and session storage can only store key-value pairs, so JSON objects need to be stringified before being stored. But as with anything, there are limitations to local and session storage, such as the maximum storage size and potential issues with stringifying certain characters, and it is good to mention the security implications of storing data on the client side.
Overall, the custom hook is a convenient and efficient for handling data in React applications. If you want to explore more about three commonly used hooks: useState, useEffect, and useContext, visit our React Hooks: Exploring useState, useEffect, and useContext article.
Where to begin?
When building and publishing a custom React hook, it’s important to emphasize the importance of creating a package.json file, which acts as the Manifest for the application and includes crucial information such as the name, version, and dependencies of the module.
It is also important to ensure that the correct version number is updated before publishing to avoid any future issues. While finding some documentation on publishing React hooks, I tried to gather information from various sources to fully understand the process. Additionally, different applications may require compatibility with different file types, such as ES6 and CommonJS.
Dependencies and plugins for roll up
Building the code for distribution, I initially used webpack but found it too complex for this specific use case and switched to roll up. Roll up is a simple bundler allowing different input formats and generating common JS and ES modules as output files. Then, it's necessary to install plugins for roll up, including those for TypeScript and handling dependencies.
Making it work as a module
Creating custom React hooks and deploying them as modules have many challenges, including the lack of documentation available. I had to go through multiple iterations to get the hooks to work as desired. Something to emphasize is the importance of peer dependencies to avoid installation conflicts.
On the other hand, roll up is crucial for building the code for CommonJS and ES Modules so that the module is available and compatible for multiple React projects. Overall, I highlight the importance of thorough understanding and careful configuration when publishing custom React hooks.
Documenting as much as possible
While developing the custom hook locally, it worked smoothly, but as soon as I began testing it on a real project, it wasn’t working as expected. I've learned that to avoid this issue, React and any other dependencies shared between the module and the application should be handled as peer dependencies.
So, I created an example using Create React App to test the hook during the development phase and was able to create a valid development environment that allowed me to test the custom React hook as if it were installed on an existing React application.
It's important to have a well-documented README file to make it easier for users to understand and use the custom hook. Also, the whole process needs to be transparent about the changes made in each version, with a proper license and relevant keywords in the README to clarify their functionality for other developers and users.
The documentation was made using Markdown on the npm README and included an overview of the hook, explaining how it works under the hood and providing additional resources for users to learn more about specific functionalities.
Creating and publishing custom hooks
My main goal in creating a custom React hook was to avoid using Redux and simplify global state management in the project. I have been using this code for some time without any major issues, except for some minor bugs caused by unhandled data structures.
The process of publishing a custom React hook works like this: once the package.json file is ready and all the necessary build steps are completed, publishing the package is as simple as running "npm publish". The correct version number and the build and output files should be in place before publishing. The command "npm unpublished" is particularly useful for cases where changes were made to the version number but were not reflected in the build.
Additionally, I have plans to develop a bundler tool for creating simple hooks and publishing them easily. Always remember to test and feel comfortable with the hook before publishing it.
Creating a custom React hook was a really interesting challenge, as it exposed your very own needs and capabilities to a world of developers. There are many use cases for custom React hooks, and each developer has a world of options to develop, create, and share useful tools with the community. I hope that this article provides the tools to allow you to take that next step and publish that custom hook that you find so useful.
If you’re interested in watching a full talk about this topic, check out this video: https://youtu.be/UTMDi4aBrWE