Last active
March 12, 2022 03:23
-
-
Save gragland/ca6806dbb849efa32be8a6919e281d09 to your computer and use it in GitHub Desktop.
React Hook recipe from https://usehooks.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@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".