I'm trying to stop the animation once the data has loaded. For the sake of testing, I'm using a timer to simulate state change (data has loaded) to interrupt animation. The problem is that the animation keeps running after the state has changed.
const [isLoading, setIsLoading] = useState(false);
const animationRef = useRef(new Animated.Value(0)).current;
const loadData = () => {
setIsLoading(true);
setTimeout(() => {
setIsLoading(false);
}, 3000)
}
useEffect(() => {
const rotateElement = () => {
animationRef.setValue(0);
Animated.timing(animationRef, {
toValue: 1,
duration: 1500,
easing: Easing.linear,
useNativeDriver: true,
}).start(rotateElement);
};
if (isLoading) {
rotateElement();
} else {
Animated.timing(animationRef).stop();
}
}, [isLoading, animationRef]);
const spin = animationRef.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg'],
});
Snack: https://snack.expo.dev/@wastelandtime/timer
CodePudding user response:
Only try to remove the parameter rotateElement from start.
const rotateElement = () => {
animationRef.setValue(0);
Animated.timing(animationRef, {
toValue: 1,
duration: 1500,
easing: Easing.linear,
useNativeDriver: true,
}).start();
CodePudding user response:
You could set a really long duration, ideally as long as your configured timeout. Then, you wouldn't need to call the start
function passing the rotateElement
as callback as Ivan suggested. That way, when you call the stop
method, it will work as desired.
Another option would be using the react-native-reanimated package for writing this function in a more declarative way, making sure that the animation would run as long as you need it to.
I edited your snack, implementing the reanimated alternative: https://snack.expo.dev/@scalfs/timer