Building & Testing React Hooks with NPM

martinpersson

Martin Persson

Posted on September 12, 2023

Building & Testing React Hooks with NPM

Table of Contents

  1. Introduction
  2. Setting Up the Project
  3. Rollup Configuration
  4. Create Our Hook
  5. Testing
  6. Conclusion

Introduction

This tutorial aims to guide you through setting up an NPM package specifically designed for React projects. You'll learn how to create and test a custom hook as well.

Links:

Previous NPM tutorial

Repo for this tutorial

What you will learn:

  • NPM Package Setup: Steps to create an NPM package for React projects or custom component libraries.
  • Custom Form Hook Creation: How to build a simple but extensible custom hook.
  • Testing in React: Utilize Jest and React Testing Library to test React components and hooks.

This tutorial builds upon a previous guide where we created a basic NPM package. If you haven't checked that out yet, you might want to start there.

Setting up the project

Firstly, ensure you have Node and npm installed. To kickstart your project, clone the starter code from the GitHub repository:

git clone https://github.com/Mumma6/npm-package-tutorial

Navigate into the project directory:

cd npm-package-tutorial/

After you've cloned the starter code, you'll want to set up your own GitHub repository. Here is how to do that:

  1. Create a New Repository on GitHub:

    • Go to your GitHub account and create a new repository.
    • Do not initialize the new repository with a README, .gitignore, or license. This empty repository will be linked to your local project.
  2. Change the Remote URL:

    • Open your terminal and navigate to your local project directory.
    • Type git remote -v to list the current configured remote repository for your fork.
    • Run git remote set-url origin YOUR-NEW-REPOSITORY-URL.git to change the repository URL to your newly created repository.
  3. Verify the Remote URL:

    • Again, run git remote -v to verify that the remote URL has been updated.
  4. Push to New Repository:

    • Run git push -u origin main (or git push -u origin master depending on your default branch name) to push your local code to your own GitHub repository.

After these steps, your local repository will be linked to your new GitHub repository, and you can start making commits and pushing changes.

Note: If you plan to publish this package, make sure to change the name in your package.json to avoid conflicts with existing packages.

Install Dependencies

Install React and React DOM. We'll use version 17 to maintain compatibility with React Testing Library:

npm i react@17 react-dom@17 @types/react@17 @types/react-dom@17

Rollup Configuration

Update your Rollup configuration to include React and React DOM as external dependencies:

const typescript = require("rollup-plugin-typescript2")
const pkg = require("./package.json")

module.exports = {
  input: 'src/index.ts',
  output: [
    {
      file: pkg.main,
      format: 'cjs',
      exports: 'named',
      sourcemap: true,
      strict: false
    }
  ],
  plugins: [
    typescript()
  ],
  external: ['react', 'react-dom']
}
Enter fullscreen mode Exit fullscreen mode

Create our hook

Let's create our custom form hook. For simplicity, the hook will be minimal:

In you index.ts file create this.

import { useState } from "react"

export function useForm(formData: any) {
  const [values, setValues] = useState(formData)

  return {
    values,
    setValues,
  }
}
Enter fullscreen mode Exit fullscreen mode

Testing

For testing we are going to use Jest and React Testing Library.

Jest

Jest is a popular testing framework in the JavaScript ecosystem that comes with a lot of features out-of-the-box, like mocking, assertions, and snapshot testing. It's widely used in the React community, partly because create-react-app includes it by default.

React Testing Library

React Testing Library is built on top of Jest and provides a set of utilities to test React components. It encourages better testing practices and makes it easier to find elements and interact with them in a way that resembles how the end-user would.

Testing Hooks with @testing-library/react-hooks

While React Testing Library primarily focuses on React components, @testing-library/react-hooks is an extension that allows us to test React hooks in isolation from the components that use them. This is particularly useful for your tutorial since you're building a hook.

The renderHook and act Functions

In our test example, we use two primary functions: renderHook and act.

  • renderHook: This function "renders" your hook in a testing environment, much like render does for components. It returns an object that contains the hook's return value, among other things.
  • act: When you need to interact with your hook (for example, to change a state variable), wrap those interactions in an act function to ensure that all updates related to these actions have been processed and applied to the DOM before you make any assertions.

To test our hook, install the required testing libraries:

npm i @testing-library/react-hooks @testing-library/jest-dom jest-environment-jsdom

Create a file called setupTests.ts and add the following line:

import "@testing-library/jest-dom"
Enter fullscreen mode Exit fullscreen mode

Update your Jest configuration to include the new environment and setup file:

module.exports = {
  preset: 'ts-jest',
  testMatch: ["**/__tests__/**/*.test.ts"],
  testEnvironment: 'jest-environment-jsdom',
  setupFilesAfterEnv: ['./setupTests.ts'],
};
Enter fullscreen mode Exit fullscreen mode

Now, create a folder called __tests__ and add a test file index.test.ts with the following content:

import { renderHook, act } from "@testing-library/react-hooks"
import { useForm } from "../src/index"

describe("useFormHook", () => {
  test("should update form values", () => {
    const { result } = renderHook(() => useForm({ name: "", email: "" }))

    act(() => {
      result.current.setValues({ name: "John", email: "john@example.com" })
    })

    expect(result.current.values).toEqual({ name: "John", email: "john@example.com" })
  })
})
Enter fullscreen mode Exit fullscreen mode

You can now run the test with npm test

Conclusion

Congratulations on making it to the end of this tutorial! You've successfully built an NPM package tailored for React projects, complete with a custom hook. Not only did you develop the hook, but you also ensured its robustness by writing tests using Jest and React Testing Library. This not only amplifies the quality of your package but also provides peace of mind when integrating it into larger, more complex systems.

What's more, your package is now ready for publishing on NPM, opening up the possibility for other developers to make use of your work in their projects. If you're unsure about how to publish your package, you can refer back to my previous guide for a detailed walk-through on publishing it to NPM.

As a next step, you might consider adding more features to your custom hook, or perhaps even expand it into a full-fledged React component library. The possibilities are endless, and the foundations laid in this tutorial will serve you well as you continue on your journey in React development.

💖 💪 🙅 🚩
martinpersson
Martin Persson

Posted on September 12, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related