Skip to content

Instantly share code, notes, and snippets.

@mykeels
Last active April 14, 2022 14:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mykeels/04f85b127c0d5c144f7db6ae3a6e830c to your computer and use it in GitHub Desktop.
Save mykeels/04f85b127c0d5c144f7db6ae3a6e830c to your computer and use it in GitHub Desktop.
A simple hook, showing dependency inversion

Here, we'll explore loosely coupling react hooks with dependency inversion as a way to manage side effects.

NB: The hooks code given here, uses react-query hooks for simplicity cos I'm rushing to write this. I hope that's not a problem. Perhaps, someone will write the equivalent implementations using out-of-the-box react hooks.

We'll consider a simple react hook, that fetches a list of users in two ways:

1. No dependency inversion

const useFetchUsers = () => {
  const { data } = useQuery("cache:users", () => fetch("https://api.example.com/users"));
  return data;
};

Using this is simple:

const users = useFetchUsers();

But we've lost the ability to explicitly specify how the hook should fetch users, without using a mocking library.

2. With Dependency Inversion

/**
* @param {() => Promise<any[]>} fetchUsers
*/
const useFetchUsers = ({ fetchUsers }) => {
  const { data } = useQuery("cache:users", fetchUsers);
  return data;
}

Here, we pass fetchUsers as a dependency in the props. This means, our hook is not tightly-coupled to a particular way of fetching users.

To use, we write:

const users = useFetchUsers({
  fetchUsers: () => fetch("https://api.example.com/users")
});

Why?

The main difference between the two is having implicit vs explicit dependencies. I believe explicitly declaring dependencies, better adheres to the functional paradigm that react tries to emulate, and makes for more testable code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment