microsoft / react-native-windows

A framework for building native Windows apps with React.
https://microsoft.github.io/react-native-windows/
Other
16.25k stars 1.14k forks source link

await blocking animation when useNativeDriver: true #9322

Open jbcullis opened 2 years ago

jbcullis commented 2 years ago

Problem Description

If you have a function that fetches data using async/await, and then run an Animated.timing at the end of that function, the animation will not run. Changing useNativeDriver to false sees the animation run correctly, otherwise changing the Animated.timing to include a force update (.start(() => this.forceUpdate())) will show the UI abruptly, but not animate.

Steps To Reproduce

Add an offset to the state this.setState({ViewOffset: new Animated.Value(300)});

Function to get data and run animation - will slide ui in from right

async Show() {
   await //Fetch some data (in our case from a sqlite database)
   Animated.timing(this.state.ViewOffset, {duration: 200, toValue: 0, useNativeDriver: true}).start();
}

UI

<View style={{position: 'absolute', top: 0, right: 0, bottom: 0, left: 0}}>
   <Animated.View style={{position: 'absolute', top: 0, bottom: 0, right: 0, width: 300, backgroundColor: 'transparent', transform: [{translateX: this.state.ViewOffset}]}}>
      <View style={{position: 'absolute', top: 0, right: 0, bottom: 0, backgroundColor: '#fafafa', width: 300}}>

      </View>
   </Animated.View>
</View>

Expected Results

Animation should run.

CLI version

npx react-native --version

Environment

System:
    OS: Windows 10 10.0.22000
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 21.85 GB / 31.73 GB
  Binaries:
    Node: 16.13.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.17 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 8.1.3 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK: Not Found
    Windows SDK:
      AllowDevelopmentWithoutDevLicense: Enabled
      AllowAllTrustedApps: Enabled
      Versions: 10.0.18362.0, 10.0.19041.0, 10.0.22000.0
  IDEs:
    Android Studio: Not Found
    Visual Studio: 17.0.31912.275 (Visual Studio Community 2022)
  Languages:
    Java: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2
    react-native: 0.66.0 => 0.66.0
    react-native-windows: 0.66.5 => 0.66.5
  npmGlobalPackages:
    *react-native*: Not Found

Target Platform Version

10.0.19041

Target Device(s)

Desktop

Visual Studio Version

No response

Build Configuration

Debug

Snack, code example, screenshot, or link to a repository

No response

ghost commented 2 years ago

Many of our core contributors are taking some much needed vacation throughout December 2021. Thank you for being patient while we relax, recharge, and return to a normal responsiveness in January 2022. In the meantime feel free to continue to pose questions, open issues, and make feature requests - you just may not get a response right away.

chrisglein commented 2 years ago

Animated.timing(this.state.ViewOffset, {duration: 200, toValue: 0, useNativeDriver: true}).start();

ViewOffset is not one of the XAML composition animation options that can be triggered by useNativeDriver, so it doesn't know how to animate this. That's a gap between RN animations and XAML animations to date, not yet implemented.

As a workaround you should be able to use native animations for Translate. Does that work for you?

chrisglein commented 2 years ago

See related discussion in similar issues like this one: #9249.

jbcullis commented 2 years ago

@chrisglein in the example above, ViewOffset is the prop where I'm storing the AnimatedTiming value, the transform is using translateX like so: transform: [{translateX: this.state.ViewOffset}]

rozele commented 2 years ago

Just to clarify - the animation works correctly if you don't fetch data / do some async operation? Have you tried this on other platforms (iOS / Android)?

jbcullis commented 2 years ago

@rozele Yes, works on ios, macos, and android.

On further testing, it seems to matter how much data is returned. I just checked a UI that returns a single row before running the animation and it did run, but not smooth. I have other screens that have a couple of calls to get single rows for the UI setup and those do not load. Could it be a timing issue?

I also tested using await vs .then and both yield the same result.