npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

granular-hooks

v1.1.0

Published

The React hooks you know, with added granularity

Downloads

18,031

Readme

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:

  • [x] 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.