Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ContextMenuView doesn't re-render properly on tab navigation #65

Open
PierrotAWB opened this issue May 16, 2023 · 3 comments
Open

ContextMenuView doesn't re-render properly on tab navigation #65

PierrotAWB opened this issue May 16, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@PierrotAWB
Copy link

First, thanks to those who've worked on this library. Aside from this singular problem, it's been a pleasure working in it.

I'm facing an issue which is similar to, but as far as I can tell, distinct from #34.

The goal is to implement a 'like' button on a ContextMenuView. Each time the button's clicked, it toggles a state variable and the UI should update accordingly. This change should persist even as the menu's hidden (if I 'like', then hide the menu and open it again, it should still indicate that I've 'liked').

I've produced a minimal example to illustrate the problem: although the button works initially, as soon as I navigate to another tab and back, it stops re-rendering properly. Both the UI and a console.log() I've included in the code indicate that the state variable (favourite) holds the correct value at all times. The issue is that it's no longer the case that clicking 'like' is immediately reflected in the UI (the menu does not re-render properly).


import React, {useState} from 'react';
import { Text, View, TouchableOpacity, Button, StyleSheet } from 'react-native';
import { ContextMenuView } from 'react-native-ios-context-menu';
import {
  NavigationContainer, useFocusEffect,
} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="First" component={Tab1} />
        <Tab.Screen name="Second" component={Tab2} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

function Tab1({ navigation }) {
  const [favourite, setFavourite] = useState(false);

  useFocusEffect(() => {
    console.log(`Current value of favourite: ${favourite}`);
  });

  const toggleFavourite = () => {
    setFavourite((prev) => !prev);
  }

  return (
    <TouchableOpacity
      style={styles.container}
      onPress={async () => { navigation.navigate("Second") }}
    >
      <ContextMenuView
        style={{
          backgroundColor: "white",
          width: "100%",
          alignItems: "center",
        }}
        useActionSheetFallback={false}
        onPressMenuItem={({ nativeEvent }) => {
          console.log("nativeEvent: ", nativeEvent);
          switch (nativeEvent.actionKey) {
            case "HEART":
              toggleFavourite();
              break;
          }
        }}
        menuConfig={{
          menuTitle: "",
          menuItems: [
            {
              actionKey: "HEART",
              actionTitle: `${favourite ? "Unlike" : "Like"}`,
              menuAttributes: ['keepsMenuPresented'],
              icon: {
                type: "IMAGE_SYSTEM",
                imageValue: {
                    systemName: (favourite
                  ? 'heart.fill'
                  : 'heart'
                ),
                },
              },
            },
          ],
        }}
      >
      <View style={{height: 100, justifyContent: "center"}}>
        <Text style={{fontSize: 14}} numberOfLines={2}>
          Hold to pop out!
        </Text>
      </View>
      </ContextMenuView>
    </TouchableOpacity>
  );
}

function Tab2({navigation}) {
  return (
    <View style={{ flex: 1, justifyContent: "center"}}>
      <Button title="Go back" onPress={() => navigation.navigate("First")} />
    </View>
  );
}


const styles = StyleSheet.create({
  container: {
    flexDirection: "row",
    justifyContent: "center",
    width: "100%",
  }
});

minimal.mov

Environment:

  • MacOS 13.0.1
  • iOS 16.1
  • React Native 0.71.7
  • react-native-Ios-context-menu 1.15.3
@dominicstop
Copy link
Owner

hi, thank you for submitting an issue; i’ll try to debug this in the weekend ahakhskdkffkfjl

this might be (another) bug with the cleanup logic, or maybe the changes to the menuConfig prop is not being detected?

hopefully, it’s not too hard to fix

@nandorojo
Copy link
Collaborator

It's possible this is due to react-freeze. I wonder if toggling enableFreeze from react-native-screens changes anything.

@nandorojo nandorojo added the bug Something isn't working label Oct 16, 2023
@nandorojo
Copy link
Collaborator

@PierrotAWB can you try adding this to the child of the context menu:

<Pressable delayLongPress={100} onLongPress={() => {}}>
  {child}
</Pressable>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants