React-native-reanimated: Animated.View jumps position on mount on all platforms

Created on 27 Apr 2020  路  3Comments  路  Source: software-mansion/react-native-reanimated

Description

Mounting

<Animated.View style={{ position: "absolute", bottom: new Animated.Value(0) }} />

results in the view briefly appearing at the top of its parent (as if we'd set top: 0) before subsequently jumping down into its correct position. This results in a janky-looking UI.

I've been able to reproduce this bug on all platforms.

Screenshots

Here's a screen capture: https://drive.google.com/file/d/1l7UdF-nZmzLsXpnzHW3WfEL4UxAcygTL/view?usp=sharing

Steps To Reproduce

  1. Open https://snack.expo.io/@bdrobinson/jumpy-animated.view . I can reproduce the bug on the embedded web simulator, but it also reproduces on my physical android device.
  2. Press the "Trigger remount!" button a few times in quick succession.

Expected behavior

Each time you press "Trigger remount!", nothing changes visually.

Actual behavior

Each time you press "Trigger remount!", the green footer briefly flashes at the top of the screen, then jumps back down to the bottom.

Interestingly, if you change bottom: new Animated.Value(0) to bottom: 0, the bug goes away.

Snack or minimal code example

https://snack.expo.io/@bdrobinson/jumpy-animated.view

Package versions

I'm pretty sure this is a bug that affects all platforms (Web, iOS, Android).

Verified it on Expo v37.0.0, and also a normal RN app with the following versions:

  • React: 16.9.0
  • React Native: 0.61.2
  • React Native Reanimated: 1.8.0

Thanks very much!

馃悶 Bug 馃コcan-repro

Most helpful comment

All 3 comments

Hey @bdrobinson

I have the same problem. temporary solution that seems to work is to do a small "rerender" with the help of useLayoutEffect so it is sync.

import {useLayoutEffect, useState} from 'react';
export default function useReanimatedFlickerFix() {
  const [, setIsMounted] = useState(false);

  //
  // use the layout effect so this is done in the same cycle
  //
  useLayoutEffect(() => {
    setIsMounted(true);
  }, []);
}

then, in the component that is flickering, simply use the hook (in Functional Components)

... useReanimatedFlickerFix(); ...

Should be fixed by #1027.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zxccvvv picture zxccvvv  路  3Comments

sa8ab picture sa8ab  路  3Comments

jwhscholten picture jwhscholten  路  4Comments

colinux picture colinux  路  3Comments

levibuzolic picture levibuzolic  路  3Comments