So I've been struggling with the getting the well-known usePrevious hook properly for me. My particular problem is that I have a state whose value is computed using a hook, and I want to know the previous value of that state as well. The hook's return value changes based on its dependencies. A simplified example is given below (in actuality, my hook is looking at useUrlParams and useLocation hooks to compute its own result:
function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
function useGetCount() {
const urlParams = useParams();
const location = useLocation();
return useCallback(() => {
// do something with urlParams and location and return a count
return Math.random();
}, [urlParams, location]);
}
const MyComponent: React.FC<{}> = () => {
const getCount = useGetCount();
const [count, setCount] = useState<number>();
const prevCount = usePrevious(count);
useEffect(() => {
const newValue = getCount();
setCount(value => value === newValue ? value : newValue);
}, [getCount]);
useEffect(() => {
console.log(`${prevCount} -> ${count}`);
}, [count, prevCount]);
return null;
}
I'm expecting this code to print:
undefined -> 0.41999121265420203
However, the above code prints:
undefined -> undefined
undefined -> 0.41999121265420203
If I instead change the above code to:
const [count, setCount] = useState<number>(getCount());
It prints:
undefined -> 0.4827576508527609
0.4827576508527609 -> 0.4486071253712367
If I initialize the state with a constant and remove the useEffect to update the state, I get a single console log as expected. But I wanna achieve the same result even if I've initialized the state with the result from another hook.
I understand WHY it's printing these values. What I wanna know is HOW I can change my code to catch a single state change event without checking for undefined of newValue === oldValue.