microsoft / microsoft/react-native-windows
Native driver persists animated values after they're no longer applied
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 17.3k
- Forks
- 1.2k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 33
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.Viewthat contains a transform or opacity set to anAnimated.Value - Use
Animated.timingto animate thatAnimated.Valueto a new value, withuseNativeDriver: true - Update the
Animated.Viewsuch that it no longer has theAnimated.Valuein 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>
</>
);
};
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the JavaScript repro using Animated.View and Animated.timing with useNativeDriver, and trace how removing the animated transform or opacity from the style is handled on Windows. Done means the previously applied transform or opacity resets when the value is no longer present, with the supplied toggle scenario no longer leaving the view translated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- desktop, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100