Closed ngocle2497 closed 2 months ago
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?
@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:
@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
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
@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:
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.executeOnUIRuntimeSync
, which, as the name suggests, runs the value changing synchronously on UI thread
Description
When i call setState after update reanimated value, animated view update incorrect Reanimared 3.8.1 work correctly for both android and ios Case 1: use useAnimatedStyle -> Animated view stuck on multiple view Case 2: use inline style -> Animated view delay update
https://github.com/software-mansion/react-native-reanimated/assets/43195241/8a9fdc80-3292-463a-aba7-7dd5063fd4b3
https://github.com/software-mansion/react-native-reanimated/assets/43195241/01c3cdd7-5013-4399-a643-955f58514936
Steps to reproduce
const Item = ({ position, index, onPress, }: { position: SharedValue;
index: number;
onPress: (index: number) => void;
}) => {
const handlePress = () => {
onPress(index);
};
const style = useAnimatedStyle(() => { return { backgroundColor: position.value === index ? '#3498db' : 'transparent', borderBottomColor: position.value === index ? '#3498db' : 'transparent', }; });
return (
); };
const App = () => { const position = useSharedValue(0); const [selectedIndex, setSelectedIndex] = useState(position.value);
const onPress = (index: number) => { position.value = index; setSelectedIndex(index); };
const renderItem = (item: number) => { return (
};
useEffect(() => { // TODO: call api or some effect }, [selectedIndex]);
return (
); };
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;