Fix optimistic state (#11556)

This commit is contained in:
Nicolas Mowen 2024-05-27 06:59:26 -06:00 committed by GitHub
parent 7a9ee63bd3
commit be147d218b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -3,11 +3,11 @@ import { useState, useEffect, useCallback, useRef } from "react";
type OptimisticStateResult<T> = [T, (newValue: T) => void]; type OptimisticStateResult<T> = [T, (newValue: T) => void];
const useOptimisticState = <T>( const useOptimisticState = <T>(
initialState: T, currentState: T,
setState: (newValue: T) => void, setState: (newValue: T) => void,
delay: number = 20, delay: number = 20,
): OptimisticStateResult<T> => { ): OptimisticStateResult<T> => {
const [optimisticValue, setOptimisticValue] = useState<T>(initialState); const [optimisticValue, setOptimisticValue] = useState<T>(currentState);
const debounceTimeout = useRef<ReturnType<typeof setTimeout> | null>(null); const debounceTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);
const handleValueChange = useCallback( const handleValueChange = useCallback(
@ -37,6 +37,16 @@ const useOptimisticState = <T>(
}; };
}, []); }, []);
useEffect(() => {
if (currentState != optimisticValue) {
setOptimisticValue(currentState);
}
// sometimes an external action will cause the currentState to change
// without handleValueChange being called. In this case
// we need to update the optimistic value so the UI reflects the change
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentState]);
return [optimisticValue, handleValueChange]; return [optimisticValue, handleValueChange];
}; };