React-native-reanimated: How to use setState in worklet

Created on 25 Aug 2020  路  7Comments  路  Source: software-mansion/react-native-reanimated

Description

how to change state or same in reanimated v2 events

Code

js const x = useSharedValue(0); const [state , setState] = React.useState(false); const gestureHandler = useAnimatedGestureHandler({ onStart: (_, ctx) => { ctx.startX = x.value; }, onActive: (event, ctx) => { x.value = ctx.startX + event.translationX; }, onEnd: _ => { x.value = withSpring(0); setState(true); // <- how to use this here }, });

Package versions

  • React:
  • React Native:
  • React Native Reanimated: 2.0.0-alpha.5
鉂換uestion 馃彔 Reanimated2

Most helpful comment

Yeah @karol-bisztyga, as well as setState(v => !v) I couldn't get to work. But I mean the provided code still works as expected :)

All 7 comments

Could you post more code? The code you provided works as expected on alpha.5.

import React from 'react';
import { TapGestureHandler } from 'react-native-gesture-handler';
import { View } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedGestureHandler,
  withSpring,
} from 'react-native-reanimated';

export default function App() {
  const x = useSharedValue(0);
  const [state, setState] = React.useState(false);

  console.log(state);

  const handler = useAnimatedGestureHandler({
    onStart: (_, ctx) => {
      ctx.startX = x.value;
    },
    onActive: (event, ctx) => {
      x.value = ctx.startX + event.translationX;
    },
    onEnd: (_) => {
      x.value = withSpring(0);
      setState(true); // <- how to use this here
    },
  });

  return (
    <View
      style={{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      }}
    >
      <TapGestureHandler onGestureEvent={handler}>
        <Animated.View
          style={{ height: 100, width: 100, backgroundColor: 'red' }}
        />
      </TapGestureHandler>
    </View>
  );
}

No @terrysahaidak it does not work properly, it does not read a proper value of a state on UI thread. Try with the following code and you'll see: setState(!state); // <- how to use this here

Yeah @karol-bisztyga, as well as setState(v => !v) I couldn't get to work. But I mean the provided code still works as expected :)

Yeah @karol-bisztyga, as well as setState(v => !v) I couldn't get to work. But I mean the provided code still works as expected :)

Yes ! :)
i just made an example
i meant can't access xD

Fixed in https://github.com/software-mansion/react-native-reanimated/pull/1165
Now this code works as expected

import React from 'react';
import { TapGestureHandler } from 'react-native-gesture-handler';
import { View } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedGestureHandler,
  withSpring,
} from 'react-native-reanimated';

export default function App() {
  const x = useSharedValue(0);
  const [state, setState] = React.useState(false);

  console.log('rerender ' + state);

  const handler = useAnimatedGestureHandler({
    onStart: (_, ctx) => {
      ctx.startX = x.value;
    },
    onActive: (event, ctx) => {
      x.value = ctx.startX + event.translationX;
    },
    onEnd: (_) => {
      x.value = withSpring(0);
      setState(!state); // <- how to use this here
    },
  });

  return (
    <View
      style={{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      }}>
      <TapGestureHandler onGestureEvent={handler}>
        <Animated.View
          style={{ height: 100, width: 100, backgroundColor: 'red' }}
        />
      </TapGestureHandler>
    </View>
  );
}

I'm getting an Error "Tried to synchronously call function {bound dispatchAction} from a different thread."
When I use setCurrentIndex(x => x + 1) within the onEnd callback

iOS
RN: 0.63.4,
react-native-gesture-handler: 1.9.0,
react-native-reanimated: 2.0.0-alpha.9.2

@CDBridger hey 馃憢 I think you missed the full error message there. There should be more:

Solution is:
a) If you want to synchronously execute this method, mark it as a Worklet
b) If you want to execute this method on the JS thread, wrap it using runOnJS

https://docs.swmansion.com/react-native-reanimated/docs/api/runOnJS

Was this page helpful?
0 / 5 - 0 ratings