GithubHelp home page GithubHelp logo

Comments (5)

szydlovsky avatar szydlovsky commented on June 2, 2024 1

@ngocle2497 Hello! This is a really interesting issue. Let me explain it:
In your example, setting a value of a SharedValue is a asynchronous operation - its value change is scheduled and it takes around 1-2 frames to get the value on both threads. Meanwhile, you change the React state immediately after it, expecting that the new render (caused by the changed state) will contain the new SharedValue value - which isn't there because it is scheduled a little bit later.
Such situations can be nicely fixed by usage of react-native-gesture-handler, which offers handling the gestures reactively and is fully integrated with Reanimated. I have re-written your example using it (keep in mind that your app needs to have a GestureHandlerRootView at its root for the gestures to work - see GH installation guide):

Fixed example code:

Code
import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Animated, {
  SharedValue,
  useAnimatedStyle,
  useSharedValue,
  runOnJS,
} from 'react-native-reanimated';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';

const Item = ({
  position,
  index,
}: {
  position: SharedValue<number>;
  index: number;
}) => {
  const style = useAnimatedStyle(() => {
    return {
      backgroundColor: position.value === index ? '#3498db' : 'transparent',
      borderBottomColor: position.value === index ? '#3498db' : 'transparent',
    };
  });

  return (
    <View style={styles.item}>
      <Animated.View style={[StyleSheet.absoluteFillObject, style]} />
      <Text>Item: {index}</Text>
    </View>
  );
};

const App = () => {
  const position = useSharedValue(0);
  const [selectedIndex, setSelectedIndex] = useState<number>(position.value);

  const renderItem = (item: number) => {
    const tap = Gesture.Tap().onEnd(() => {
      position.value = item;
      runOnJS(setSelectedIndex)(item);
    });

    return (
      <GestureDetector gesture={tap}>
        <Item position={position} key={item} index={item} />
      </GestureDetector>
    );
  };

  useEffect(() => {
    // TODO: call api or some effect
  }, [selectedIndex]);

  return (
    <View style={styles.container}>
      <View style={styles.rowItem}>{[0, 1, 2, 3, 4, 5].map(renderItem)}</View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  rowItem: {
    flexDirection: 'row',
    columnGap: 4,
    width: '100%',
    height: 100,
  },
  item: {
    height: 100,
    width: 50,
    borderBottomWidth: 2,
    borderColor: 'transparent',
    overflow: 'hidden',
  },
});

export default App;

from react-native-reanimated.

github-actions avatar github-actions commented on June 2, 2024

Hey! πŸ‘‹

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

from react-native-reanimated.

ngocle2497 avatar ngocle2497 commented on June 2, 2024

@szydlovsky thank for explain. I discovered this issue when running the project on production environment. Actually, it's not just an example, the example just describes how to make an error. in my project i have 1 swipeable list. When entering a menu in a swipeable section, I also use a gesture handler (tap gesture) to close the swipeable action after switching screens. And you know, when switching screens, setstate happens very often (turn on loading, update data,...). that is swipeable and not closeable. I will upload a video of my today's production project around today (GMT +7). Hope you can fix this error for me. Thank

from react-native-reanimated.

ngocle2497 avatar ngocle2497 commented on June 2, 2024
RPReplay_Final1715636546.mp4

https://github.com/software-mansion/react-native-reanimated/assets/43195241/ddb4518e-547d-495c-a66c-9178c8cb8b36
I also use react navigation native stack
@szydlovsky can u open this issue by my video?
issue 1: Tab alert not active
Issue 2: swipeable cannot closeable

from react-native-reanimated.

szydlovsky avatar szydlovsky commented on June 2, 2024

@ngocle2497 Hi again. Unfortunately, the example video is not enough te re-open the issue. I know that we cannot access the source code, because it is a private company project, but that leaves us with only guessing what could be wrong. You can try making a more complex repro out of it and posting it here - then I will reopen the issue. Other than that, I can give you some tips to check in your code:

  • as I said previously, setting the SharedValue value is a scheduled, asynchronous operation - so any renders directly afterwards may not use the changed value. If the value is being changed as a result of some tap - then you can do it in react-native-gesture-handler gesture callback, which makes it run on UI thread and execute synchronously.
  • there is one more, a bit niche way to fix such stuff - you can wrap the value setting in Reanimated's executeOnUIRuntimeSync, which, as the name suggests, runs the value changing synchronously on UI thread
  • there is always a third way - if you would like us to take a peek into the code (assuming a sufficient NDA) you could contact us through our business contact form: https://swmansion.com/contact/projects

from react-native-reanimated.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.