Skip to content

Instantly share code, notes, and snippets.

@gragland
Last active March 12, 2022 03:23
Show Gist options
  • Save gragland/ca6806dbb849efa32be8a6919e281d09 to your computer and use it in GitHub Desktop.
Save gragland/ca6806dbb849efa32be8a6919e281d09 to your computer and use it in GitHub Desktop.
React Hook recipe from https://usehooks.com
import React, { useState, useEffect, useRef } from 'react';
// Usage
function MyComponent({ obj }) {
const [state, setState] = useState();
// Use the previous obj value if the "id" property hasn't changed
const objFinal = useMemoCompare(obj, (prev, next) => {
return prev && prev.id === next.id;
});
// Here we want to fire off an effect if objFinal changes.
// If we had used obj directly without the above hook and obj was technically a
// new object on every render then the effect would fire on every render.
// Worse yet, if our effect triggered a state change it could cause an endless loop
// where effect runs -> state change causes rerender -> effect runs -> etc ...
useEffect(() => {
// Call a method on the object and set results to state
return objFinal.someMethod().then((value) => setState(value));
}, [objFinal]);
// So why not pass [obj.id] as the dependency array instead?
useEffect(() => {
// Then eslint-plugin-hooks would rightfully complain that obj is not in the
// dependency array and we'd have to use eslint-disable-next-line to work around that.
// It's much cleaner to just get the old object reference with our custom hook.
return obj.someMethod().then((value) => setState(value));
}, [obj.id]);
return <div> ... </div>;
}
// Hook
function useMemoCompare(next, compare) {
// Ref for storing previous value
const previousRef = useRef();
const previous = previousRef.current;
// Pass previous and next value to compare function
// to determine whether to consider them equal.
const isEqual = compare(previous, next);
// If not equal update previousRef to next value.
// We only update if not equal so that this hook continues to return
// the same old value if compare keeps returning true.
useEffect(() => {
if (!isEqual) {
previousRef.current = next;
}
});
// Finally, if equal then return the previous value
return isEqual ? previous : next;
}
@nwatab
Copy link

nwatab commented Mar 12, 2022

@heyimalex Thanks for quick check. Yeah, as you said, my post causes an infinite loop and was about to destroy my computer. I updated my code that seemingly works fine.
Could you explain why you would useEffect in your code at your convenience?

I also have a question about how to "get data and edit, update into database".

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