Skip to content

gfox1984/granular-hooks

Repository files navigation

granular-hooks

The React hooks you know, with added granularity. You can read more about this on Medium.

The problem

Who hasn't been in the situation where s/he needs an effect to run only when some of its dependencies have changed? Take this code for instance:

import { useEffect } from "react";

useEffect(() => {
  if (condition) console.log("condition is true! value is", value);
  else console.log("condition is false! value is", value);
}, [value, condition]);

Here, the effect prints to the console each time value or condition change. You cannot print to the console ONLY when value changes because useEffect wants that all values used by the effect are passed in the array of dependencies.

The solution

With minimal effort, useGranularEffect allows you to splits the array of dependencies into two: primary dependencies and secondaries dependencies.

useGranularEffect guarantees that:

  • the effect only runs when the primary dependencies change
  • the cleanup function (if any) only runs when the primary dependencies change
  • when the effect runs, both primary and secondary dependencies are up-to-date

The example above can now be changed to:

import { useGranularEffect } from "granular-hooks";

useGranularEffect(
  () => {
    if (condition) console.log("condition is true! value is", value);
    else console.log("condition is false! value is", value);
  },
  [value],
  [condition]
);

Now the code only prints to the console when value changes.

Installation

npm install granular-hooks

or

yarn add granular-hooks

Usage

import { useGranularEffect } from "granular-hooks";

useGranularEffect(
  () => {
    // the effect function, use your dependencies here
    // dep1, dep2, dep3, dep4,...

    // (optional) return a cleanup function
    return () => {
      /* cleanup*/
    };
  },
  [dep1, dep2], // primary dependencies (runs when they change)
  [dep3, dep4] // secondary dependencies (does not run when they change)
);

The only difference with useEffect is that the array of dependencies is split into two (the primary dependencies and the secondary dependencies). In fact, useGranularEffect uses useEffect under the hood, thus the similarities.

See the React documentation for useEffect for more information regarding the effect function, the optional cleanup function and dependencies.

Also check the general rules of hooks.

Other hooks

granular-hooks also supports the following hooks:

The hooks have the same signature as their React equivalents, except that the array of dependencies is split into two, just like with useGranularEffect.

What's next?

Below are the features we're working on:

  • Why stop with granular effect? granular memos and callback are calling too! Stay tuned.
  • What if we could also use a custom dependency comparer (other than the default Object.is)?
  • React hooks have a great ESLint plugin that makes sure you don't forget to list dependencies when calling them. granular-hooks are still missing such tools.

FAQ

Can I leave the primary array of dependencies empty?

You can. That means that the effect will only run once, when the component is mounted (the initial render).

Can I leave the secondary array of dependencies empty?

You could but that would defeat the purpose of the hook. You might as well call useEffect directly.

Why use useGranularEffect when I can just omit some dependencies in useEffect?

While you could technically do so, it would violate the rules exposed in conditionally firing an effect:

make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders.

Having said that, it should still work as intended (see Understanding dependencies in useEffect). useGranularEffect will however help you be explicit about your dependencies and it will make sure that the effect is called with an exhaustive list of dependencies, even though this is not stricly necessary technically speaking.

About

Good old React hooks, with added granularity

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages