React-native-reanimated: useState doesn't work as expected after migrating from 1.9.0 to 1.10.0

Created on 20 Sep 2020  路  4Comments  路  Source: software-mansion/react-native-reanimated

Description

We have a TouchableOpacity component implemented using geature-handler and reanimated libraries.
You can find the implementation here:
https://github.com/wix/react-native-ui-lib/blob/master/src/incubator/TouchableOpacity.tsx

After upgrading from 1.9.0 to 1.10.0 (The issue also happens in current version of reanimated v1)
I noticed some basic functionality with React useState stopped working. It's a little difficult to explain, so I'll just show two code examples that demonstrate the issue.

I created a very basic example screen of a button with a counter.
I implemented this screen using Class component and Function component

This is the Screen's code using Function and hooks

export default () => {
  const [counter, setCounter] = useState(0);

  const count = () => {
    setCounter(counter + 1);
  };

  console.warn('counter', counter);
  return (
    <View>
      <Text>With Function</Text>

      <TouchableOpacity onPress={count}>
        <Text>{counter}</Text>
      </TouchableOpacity>
    </View>
  );
};

And this is the implementation of the same screen using Class component and setState

export default class Screen extends Component {
  state = {
    counter: 0
  };

  count = ({id}) => {
    this.setState({counter: this.state.counter + 1});
  };

  render() {
    console.warn('counter', this.state.counter);
    return (
      <View>
        <Text>With Class Screen</Text>
        <TouchableOpacity onPress={this.count}>
          <Text>{this.state.counter}</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

The issue is that while in the Class example the counter keep advance and the state is being updated on each press
In the Function example the counter doesn't seem to work, updating the state doesn't really work and the counter stays at 0.

Screenshots

Steps To Reproduce

  1. Clone react-native-ui-lib library
    https://github.com/wix/react-native-ui-lib
  2. Checkout reanimated-issue branch
  3. npm install (and cd ios && pod install)
  4. build and start the app (npm run ios)
  5. In the example screen search for "Native TouchableOpacity" and enter the screen
  6. The example screen code can be found here: https://github.com/wix/react-native-ui-lib/blob/reanimated-issue/demo/src/screens/incubatorScreens/TouchableOpacityScreen.js
  7. Press the button with the counter and see nothing updates.

Expected behavior

useState should update state when invoked from Tappable components implemented using gesture-handler and reanimated libraries.

Actual behavior

While this.setState work as expected, useState hook doesn't really update the state

Snack or minimal code example

Package versions

  • React: 16.11.0
  • React Native: 0.62.2
  • React Native Reanimated: 1.10.0
  • react-native-gesture-handler: 1.6.1
馃悶 Bug

Most helpful comment

I can do that right now :>

1.13.1 should be live right now.

All 4 comments

I'm pretty sure this is related to the Code component change which now uses the useCode hook. <Code /> may misbehave now when rerender is involved (setting state rerenders). Could you revert this commit by using patch-package and check if it works as intended?

Hi @jakub-gonet,
I reverted the code of src/core/AnimatedCode.js file locally as you said and it's indeed the cause of the issue.

@jakub-gonet
Any idea when this fix will be released?

I can do that right now :>

1.13.1 should be live right now.

Was this page helpful?
0 / 5 - 0 ratings