Open
Description
Environment
react-native -v
:
react-native-cli: 2.0.1
react-native: 0.60.6
npm ls rnpm-plugin-windows
:
rnpm-plugin-windows@0.3.7
npm ls react-native-windows
:
react-native-windows@0.60.0-vnext.37
node -v
:
v10.15.0
npm -v
:
6.4.1
Then, specify:
- Target Platform Version(s): 10.0.18362
- Target Device(s): Desktop, Xbox
- Visual Studio Version: 2019
- Build Configuration: Debug and Release
Steps to Reproduce
- Pass a style to an
Animated.View
that contains a transform or opacity set to anAnimated.Value
- Use
Animated.timing
to animate thatAnimated.Value
to a new value, withuseNativeDriver: true
- Update the
Animated.View
such that it no longer has theAnimated.Value
in its styles
Expected Behavior
The transform or opacity would reset to initial values. A View translated to the right previously would have that translation removed.
Actual Behavior
The transform or opacity remain applied, even though the style no longer contains those values.
Reproducible Demo
import React from "react";
import { Animated, Easing, Text, TouchableOpacity } from "react-native";
export default class AnimationPersistRepro extends React.Component {
state = { animated: false };
translateXAnimated = new Animated.Value(0);
onPress = () => {
this.setState((state) => {
const shouldAnimate = !state.animated;
if (shouldAnimate) {
Animated.timing(this.translateXAnimated, {
duration: 400,
toValue: 100,
easing: Easing.linear,
useNativeDriver: true,
}).start();
}
return { animated: shouldAnimate };
});
};
render() {
const animatedStyle = {
transform: [{ translateX: this.translateXAnimated }],
};
const nonAnimatedStyle = {
transform: [],
};
return (
<>
<Animated.View style={this.state.animated ? animatedStyle : nonAnimatedStyle}>
<Text>Animates to the right</Text>
</Animated.View>
<TouchableOpacity onPress={this.onPress}>
<Text>Press to toggle animation. Currently animated: {this.state.animated.toString()} </Text>
</TouchableOpacity>
</>
);
}
}
----alternative repro as a function component-----
const AnimationPersistRepro = () => {
const [isAnimated, setAnimated] = useState(false);
const translateXAnimated = useRef(new Animated.Value(0));
const animatedStyle = {
transform: [ { translateX: translateXAnimated.current } ]
};
const nonAnimatedStyle = {
transform: []
};
const onPress = () => {
setAnimated(animated => {
const shouldAnimate = !animated;
if(shouldAnimate) {
Animated.timing(translateXAnimated.current, {
duration: 400,
toValue: 100,
easing: Easing.linear,
useNativeDriver: true
}).start();
}
return shouldAnimate;
});
};
return (
<>
<Animated.View style={isAnimated ? animatedStyle : nonAnimatedStyle}>
<Text>Animates to the right</Text>
</Animated.View>
<TouchableOpacity onPress={onPress}>
<Text>Press to toggle animation. Currently animated: {isAnimated.toString()} </Text>
</TouchableOpacity>
</>
);
};