perf(explorer-sidebar): memoize animation context value

Stabilize animateToOpen/animateToClose with useCallback and wrap the
provider value in useMemo so consumers don't re-render on every parent
re-render.
This commit is contained in:
Mohamed Boudra
2026-04-20 10:45:55 +07:00
parent 044546ae0c
commit 67eddbd6a9
@@ -1,4 +1,12 @@
import { createContext, useContext, useEffect, useRef, type ReactNode } from "react"; import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
type ReactNode,
} from "react";
import { useWindowDimensions } from "react-native"; import { useWindowDimensions } from "react-native";
import { useSharedValue, withTiming, Easing, type SharedValue } from "react-native-reanimated"; import { useSharedValue, withTiming, Easing, type SharedValue } from "react-native-reanimated";
import { type GestureType } from "react-native-gesture-handler"; import { type GestureType } from "react-native-gesture-handler";
@@ -93,7 +101,7 @@ export function ExplorerSidebarAnimationProvider({ children }: { children: React
backdropOpacity.value = targets.backdropOpacity; backdropOpacity.value = targets.backdropOpacity;
}, [isOpen, translateX, backdropOpacity, windowWidth, isGesturing]); }, [isOpen, translateX, backdropOpacity, windowWidth, isGesturing]);
const animateToOpen = () => { const animateToOpen = useCallback(() => {
"worklet"; "worklet";
translateX.value = withTiming(0, { translateX.value = withTiming(0, {
duration: ANIMATION_DURATION, duration: ANIMATION_DURATION,
@@ -103,9 +111,9 @@ export function ExplorerSidebarAnimationProvider({ children }: { children: React
duration: ANIMATION_DURATION, duration: ANIMATION_DURATION,
easing: ANIMATION_EASING, easing: ANIMATION_EASING,
}); });
}; }, [translateX, backdropOpacity]);
const animateToClose = () => { const animateToClose = useCallback(() => {
"worklet"; "worklet";
translateX.value = withTiming(windowWidth, { translateX.value = withTiming(windowWidth, {
duration: ANIMATION_DURATION, duration: ANIMATION_DURATION,
@@ -115,11 +123,10 @@ export function ExplorerSidebarAnimationProvider({ children }: { children: React
duration: ANIMATION_DURATION, duration: ANIMATION_DURATION,
easing: ANIMATION_EASING, easing: ANIMATION_EASING,
}); });
}; }, [translateX, backdropOpacity, windowWidth]);
return ( const value = useMemo<ExplorerSidebarAnimationContextValue>(
<ExplorerSidebarAnimationContext.Provider () => ({
value={{
translateX, translateX,
backdropOpacity, backdropOpacity,
windowWidth, windowWidth,
@@ -129,8 +136,12 @@ export function ExplorerSidebarAnimationProvider({ children }: { children: React
gestureAnimatingRef, gestureAnimatingRef,
openGestureRef, openGestureRef,
closeGestureRef, closeGestureRef,
}} }),
> [translateX, backdropOpacity, windowWidth, animateToOpen, animateToClose, isGesturing],
);
return (
<ExplorerSidebarAnimationContext.Provider value={value}>
{children} {children}
</ExplorerSidebarAnimationContext.Provider> </ExplorerSidebarAnimationContext.Provider>
); );