Skip to content

Instantly share code, notes, and snippets.

@ryanto
Created May 11, 2020 20:00
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ryanto/e2d73365e427e4bbde2127dd6d563a60 to your computer and use it in GitHub Desktop.
Depends on. Think of it like a useEffect where you unapologetically use the dependencies list to control when the effect should run.
import { usePrevious } from "./use-previous";
import { useRef, useEffect } from "react";
export const useDependsOn = (
value,
functionToRun,
{ initial = true } = {}
) => {
let serialized = JSON.stringify(value);
let previous = usePrevious(serialized);
let shouldRun = useRef(initial);
let isFirstRender = useRef(true);
if (serialized !== previous.current && (!isFirstRender.current || initial)) {
shouldRun.current = true;
}
useEffect(() => {
if (shouldRun.current) {
functionToRun();
shouldRun.current = false;
}
isFirstRender.current = false;
});
};
import { useRef, useEffect } from "react";
export const usePrevious = (value) => {
let ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref;
};
@ryanto
Copy link
Author

ryanto commented May 11, 2020

This hook lets you write a function that will run whenever a specific value in your render changes. Think of it as a way to solve the "classic componentDidMount bug" where you forget to handle updating props with componentDidUpdate.

useDependsOn(user.id, () => { fetchUser(user.id) })

useDependsOn([user.id, post.id], () => {
  fetchUsersCommentsForPost(user.id, post.id)
})

It's not the same as useEffect because it lets you opt out of dependencies that "cannot change" from your business logic's point of view. In the above example we don't set fetchUser or fetchUserCommentsForPost as things we depend on because even if the identity of those functions happen to change we know that the business logic does not.

This can help prevent unexpected effect calls when things we do not care about change.

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