Using shared values with useEffect? #3574
-
I want to fire an animation after the component is mounted. For the animation, I am using a shared value which will be updated by the callback passed to In the above piece of code (as shared by the same tutorial), the shared value variable ( However, when I try to consume/update a shared value inside What is the correct way to consume shared values inside effects? In case the shared value need not be passed as a dependency to Thanks in advance :) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
RNR's The proper way to solve this is to extract the animation startup code to a separate function in the component: // example
const fadeAnim = useSharedValue(0);
const slideAnim = useSharedValue(30);
const animatedStyle = useAnimatedStyle(
() => ({
opacity: withTiming(fadeAnim.value, { duration: 1000 }),
transform: [
{ translateY: withTiming(slideAnim.value, { duration: 1000 }) },
],
}),
[]
);
// This function is where you trigger the animation - make sure you wrap it in useCallback to avoid stack overflows
const startAnimation = useCallback(() => {
fadeAnim.value = 1;
slideAnim.value = 0;
}, [fadeAnim, slideAnim]);
useEffect(() => {
startAnimation();
}, [startAnimation]); // no errors This effectively changes nothing, but it pleases ESLint since the usage of TLDR For your code: export default function Ring({ delay }: { delay: number }) {
const ring = useSharedValue(0);
const ringStyle = useAnimatedStyle(() => {
return {
opacity: 0.8 - ring.value,
transform: [{ scale: interpolate(ring.value, [0, 1], [0, 4]) }],
};
});
const startAnimation = useCallback(() => {
ring.value = withDelay(
delay,
withRepeat(withTiming(1, { duration: 4000 }), -1, false)
);
}, [delay, ring]);
useEffect(() => {
startAnimation();
}, [startAnimation]);
return <Animated.View style={[styles.ring, ringStyle]} />;
} |
Beta Was this translation helpful? Give feedback.
Hey @mapokapo!
Your suggestion is correct but unnecessarily complicated. We don't have to create a separate function to start the animation. We can just put the SharedValue in the dependency array of the
useEffect
to satisfy eslint.So in this case it will be:
It is safe to pass all shared values that you use in the dependency array as React performs a shallow comparison of all objects and SharedValues objects don't change during renders so they won't fire the
useEf…