Content wrapped inside of ContextMenu gets invisible after navigating away
See original GitHub issueI’ve first created an issue on react-navigation, but found out that this issue is related to this library.
Current behavior
I have a FlatList (with windowSize: 1
) of messages in my chat page, but when I navigate to a new page the items in this list turn blank and have to be rerendered to be visible again.
Also interesting to note, when I navigate back, the messages stay visible, however when I navigate to a new page they turn blank in the process of navigating.
Navigate back to overview page: | Navigate to call page: |
Expected behavior
The items shouldn’t turn blank and have to be rerendered to be visible again.
Environment
package | version |
---|---|
react-native-ios-context-menu | 1.7.2 |
@react-navigation/native | 6.0.6 |
@react-navigation/native-stack | 6.2.5 |
react-native-screens | 3.10.1 |
react-native | 0.66.4 |
node | 16.10.0 |
npm or yarn | 1.22.15 |
OS | iOS 15.2.1 |
Reproduction
Snack doesn’t work, because expo doesn’t have react-native-ios-context-menu
as a native dependency, but you can use the code to reproduce it:
import * as React from 'react';
import { Text, View, Button, ScrollView } from 'react-native';
import { ContextMenu } from 'react-native-ios-context-menu';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import {
NavigationContainer,
useNavigationContainerRef,
} from '@react-navigation/native';
const Stack = createNativeStackNavigator();
function Chat({ navigation }) {
return (
<View style={{ flex: 1 }}>
<Button title="Call" onPress={() => navigation.navigate('call')} />
<ScrollView style={{ flexGrow: 1 }}>
{['hi', 'test', 'nice', 'no', 'ok', 'goodbye', 'hello'].map((x) => (
<ContextMenu
previewConfig={{ previewType: 'DEFAULT', borderRadius: 0 }}
menuConfig={{
menuTitle: '',
menuItems: [
{
menuTitle: 'React',
menuItems: ['👍', '👎', '😂', '❤️', '🚀'].map((x) => ({
actionKey: 'react-' + x,
actionTitle: x,
})),
icon: {
type: 'IMAGE_SYSTEM',
imageValue: {
systemName: 'smiley',
},
},
},
{
menuTitle: 'Delete',
// actionKey: "delete",
// actionTitle: "Delete",
menuOptions: ['destructive'],
menuItems: [
{
actionKey: 'delete',
actionTitle: 'Confirm',
menuOptions: ['destructive'],
menuAttributes: ['destructive'],
icon: {
type: 'IMAGE_SYSTEM',
imageValue: {
systemName: 'trash.fill',
},
},
},
],
icon: {
type: 'IMAGE_SYSTEM',
imageValue: {
systemName: 'trash.fill',
},
},
},
],
}}>
<View style={{ padding: 10, margin: 5 }}>
<Text>{x}</Text>
</View>
</ContextMenu>
))}
</ScrollView>
</View>
);
}
function Call() {
return (
<View style={{ flex: 1 }}>
<Text style={{ fontSize: 30 }}>Call Page</Text>
</View>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="chat" component={Chat} />
<Stack.Screen name="call" component={Call} />
</Stack.Navigator>
</NavigationContainer>
);
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (4 by maintainers)
Top Results From Across the Web
How to prevent context menu in an iframe? - Stack Overflow
The only way to prevent the context menu inside an iframe is to load your context menu prevention script inside the iframe itself....
Read more >How to: Use a Custom Context Menu with a TextBox - WPF ...
Implement a Custom Context Menu To restore the default context menu, use the ClearValue method to clear the value of the ContextMenu property. ......
Read more >Custom Right Click with Context Menu in React - YouTube
Code: https://github.com/stuyy/ context-menu -reactSupport the Channel:Become a Member: https://www.youtube.com/ansonthedeveloper/joinBecome a ...
Read more ><nav>: The Navigation Section element - MDN Web Docs
The HTML element represents a section of a page whose purpose is to provide navigation links, either within the current document or to...
Read more >ContextMenu | Apple Developer Documentation
You can create a context menu by first defining a ContextMenu container with the controls that represent the actions people can take, and...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@fobos531 hello, sorry for the late reply, haven’t been active w/ OSS lately afdghsjdjaklfjklsghshgjdfogjdf
Basically, to prevent memory leaks, a cleanup routine needs to be triggered whenever the component unmounts.
The way I’ve implemented this is through a parent view controller that listens for when a view is removed (e.g.
RNINavigationEventsReportingViewController
).The
UIVIewController.viewWillDisappear
lifecycle method gets called whenever a view is hidden. Inside that method, we check if the parentUINavigationController
’s navigation stack still contains the parent view controller.If it does, then that means the current view controller hasn’t been poppped yet, and instead, a new view controller has been pushed into the stack (and has taken focus).
Otherwise it means thats the view controller has been popped, and thus, it should notify its delegate (i.e. the
RNIContextMenu
instance) that it’s going to be removed from the navigation stack.This in turn will trigger the clean up routine.
There are two assumptions here: The 1st one is that the parent view controller is the root view controller for the screen (which might not always be the case).
The 2nd assumption is that the reason for
UIVIewController.viewWillDisappear
to trigger is due to aUINavigationController
instance changing the current active vc.Unfortunately, if either one of these assumptions are false, then this will result w/ the cleanup routine being called when it doesn’t need to be — causing the “disappearing” bug.
In the latest release (version
1.12.2
), I added ainternalCleanupMode
prop. This prop controls how the cleanup routine is triggered.You can set this prop to use 4 modes:
automatic
,viewController
,reactComponentWillUnmount
, anddisabled
— normally, you shouldn’t need to fiddle with this prop, but I’ve added it as temp. fix for when this bug happens again (and I can’t immediately fix it).viewController
mode will trigger the clean up routine via theUIViewController.viewWillDisappear
lifecycle method, whilereactComponentWillUnmount
mode on the other hand, will trigger the clean up routine via thecomponentWillUnmount
react lifecycle event.By default, the
internalCleanupMode
prop is set toautomatic
. And currently,automatic
mode defaults to usingreactComponentWillUnmount
mode — I might change this back toviewController
once i fix all the edge cases.If you are still experiencing this issue, try setting
internalCleanupMode
todisabled
and reopen this issue (feel free to tag me if I take too long respond).But for now, I’ll be closing this issue asjhskflehfkehfiljds;jflsi @Flam3rboy sorry for late response, but i hope this fixes your issue xx
Hey @dominicstop. I patched the library as follows and it has been working for me so far: