Uh oh!
There was an error while loading. Please reload this page.
Optionally create NativeAnimated value with native flag - #10657
Conversation
fbc0b18 to
ca5df24Comparejanicduplessis
commented
Nov 2, 2016
Would it be possible to update views when attaching a new animated prop to it in the same frame that react update / creates the view. I'm having another issue that might be related to this when creating a new view with an native animated prop that doesn't match the view's default. For example you have <Animated.Viewstyle={{transform: [{scale: animatedValue}]}}/>if at the time the view is created the animated value is already native and has a value of 0.5 for example the view won't have 0.5 scale untill an animation starts. Even if starting an animation at the same time as creating the view there would still be a flicker for a frame. |
ryangomba
commented
Nov 2, 2016
Couple questions: |
janicduplessis
commented
Nov 2, 2016
@ryangomba Both iOS and Android with #10663 Right now I'm doing janicduplessis@ea63ade to fix it but that can cause other issues when rerendering with setState during an animation (which I'm not really doing atm in my app so that works for me). |
janicduplessis
commented
Nov 2, 2016
I'm pretty sure this happens because we're creating views without these props so there is a time where it uses default values (no transform). |
ryangomba
commented
Nov 2, 2016
@janicduplessis any chance you could wrap this bug up in a UIExplorer example and send to me? |
classTestextendsReact.Component{state={anim: newAnimated.Value(0),views: [],}componentWillMount(){this.state.anim.__makeNative();}_createView=()=>{this.setState(state=>({views: [...state.views,{}]}));};_animate=()=>{Animated.timing(this.state.anim,{toValue: 1,duration: 500,useNativeDriver: true,}).start();};render(){return(<View><TouchableWithoutFeedbackonPress={this._createView}><View><Text>Add view</Text></View></TouchableWithoutFeedback><TouchableWithoutFeedbackonPress={this._animate}><View><Text>Animate</Text></View></TouchableWithoutFeedback>{this.state.views.map((v,i)=>(<Animated.Viewkey={i}style={[styles.block,{opacity: this.state.anim}]}/>))}</View>);}}You can add this in NativeAnimationsExample.js |
janicduplessis
commented
Nov 3, 2016
The bug happens here if you click create view a few times, the first one is fine (not sure why) but the other ones after have opacity=1 instead of 0. Then if you click animate it starts an animation and fixes the values. |
janicduplessis
commented
Nov 3, 2016
Actually it works on iOS with #10663 but not on Android. I still had the issue in my app I'll try to find a better repro. |
ryangomba
commented
Nov 3, 2016
I've got another diff coming your way to tighten up android invalidation - I think it will fix |
janicduplessis
commented
Nov 3, 2016
The issue still happens but I can't reproduce it in a simple UIExplorer example. What I think happens is:
It is only broken for 1 frame on iOS during screen transitions. |
ryangomba
commented
Nov 3, 2016
And does it happen if you mark the animated value as native when it is created? |
janicduplessis
commented
Nov 3, 2016
Yep the animated value has to be native already otherwise it works because we pass all the props on view creation. |
janicduplessis
commented
Nov 3, 2016
Passing native animated props to the component also fixes it like in this diff but will cause other issues janicduplessis@ea63ade |
janicduplessis
commented
Nov 3, 2016
I think the issue is that we create views and animated props in 2 separate JS to Native calls so if the bridge is busy and there is some delay this can happen in 2 different render frames so you see the flicker. I think to fix this we would need a way to have view creation be aware of native animated props but I don't see a simple way to do this now. |
Summary: This diff attempts to fix a number of Android native animation bugs related to incomplete node invalidation, e.g. #10657 (comment). For full correctness, we should mark any node as needing update when it is: - created - updated (value nodes) - attached to new parents - detached from old parents - attached to a view (prop nodes) cc/ janicduplessis Closes#10837 Differential Revision: D4166446 fbshipit-source-id: dbf6b9aa34439e286234627791bb7fef647c8396
hramos
commented
Nov 11, 2016
What are the next steps for this PR? Any requested changes? |
janicduplessis
commented
Nov 11, 2016
@ryangomba is this still needed with the updates to invalidations? Since we are removing the prop but updating it again when connecting the native animated prop the the view. |
ryangomba
commented
Nov 11, 2016
This is still very much needed. I think you are right that we still have a race that we need to address, but I'd prefer we loop back on that issue since you're right in saying the solution won't be simple. |
janicduplessis
commented
Nov 17, 2016
Ok, anyway thinking about it it makes more sense to have One thing we should add to this is check if the animated value is native already when we start an animation and use the native driver in that case. That way we can specify useNativeDriver only on the animated value. For example here https://github.com/facebook/react-native/blob/master/Libraries/Animated/src/AnimatedImplementation.js#L411. |
janicduplessis
commented
Nov 17, 2016
If this seems like a better pattern we can move forward with deprecating useNativeDriver on animations and animated.event in a future diff. |
ca5df24 to
f71839eCompareryangomba
commented
Nov 28, 2016
@janicduplessis I've adopted your suggestion, but apply the check earlier since the animation doesn't actually store a reference to the value it is driving. |
f71839e to
511f633Compare511f633 to
67e952aComparenihgwu
commented
Dec 29, 2016
any progress on this? |
lacker
commented
Feb 8, 2017
It looks like this pull request has been abandoned so I am going to close it. If someone is still working on this then please feel free to reopen it! |
Billy-
commented
Jul 25, 2018
@ryangomba@lacker@janicduplessis What needs to be done? This PR looks good to go, no? |
The issue this addresses was originally mentioned in #9120, but here it is again:
How to reproduce:
The problem:
You will see that the first block resets to opacity 1 unexpectedly. This is because when we originally create the block, it has a non-native opacity prop (opacity = 0.25). This value gets sent to react proper. After we mark the animated value as
__native, however, this prop is removed from the component. When prevProps and nextProps are diffed, react notices that opacity has been removed and callsupdateViewwithopacity: null, thereby resetting the value to 1.The solution
In order to avoid this behavior, I propose that native animated values be marked as
__nativewhen they are created. This would ensure that all its children would also be marked as__native, and would make the entire animation tree easier to reason about. For now, we can make this an optional config per @janicduplessis suggestion.