I am getting the error in the title on a React-Native app that I am currently working on.
I have gone through hours of troubleshooting, and there doesn't seem to be a solution online.
From what I have gathered, the following hook const [isOpen, setIsOpen] = useState(false); is causing the issue here, possibly due to order of hooks. This hook is used to toggle a menu that I have custom build. However, when I try to navigate to another screen <TouchableOpacity onPress={() => navigation.navigate('Job')}>(from screen stack, not from modal or card), the app breaks and I get the error. If I comment out the one line hook of hook const [isOpen, setIsOpen] = useState(false);, the navigation works perfectly fine.
A solution would be greatly appreciated.
config.js
export const sharedScreenOptions = (props) => {
const [isOpen, setIsOpen] = useState(false);
const toggleMenu = () => {
setIsOpen(!isOpen);
LayoutAnimation.easeInEaseOut();
};
return {
headerBackTitleVisible: false,
header: (props) => {
return (
<><GradientHeader isOpen={isOpen} {...props} />
{isOpen ? (
<TouchableOpacitystyle={{height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
backgroundColor: 'rgba(42, 44, 65, 0.5)',
position: 'absolute',
zIndex: -999,
}}
onPress={() => toggleMenu()}></TouchableOpacity>
) : null}
</>
);
},
headerRight: () => {
return (
<View style={styles.iconContainer}><TouchableOpacity onPress={() => navigation.navigate('Job')}>
<MailButton navigation={props.navigation} /></TouchableOpacity><NotificationButton navigation={props.navigation} /><TouchableOpacity onPress={() => toggleMenu()}>
{isOpen ? <CloseButton /> : <HamburgerButton />}
</TouchableOpacity></View>
);
},
headerStyle: {
backgroundColor: 'transparent',
},
};
};
Navigation.js
const JobboardStack = createStackNavigator();
const JobboardStackScreens = () => {
return (
<JobboardStack.NavigatorinitialRouteName="Jobboard"screenOptions={sharedScreenOptions}><JobboardStack.Screenname="JobBoard"component={JobboardScreen}options={{headerTintColor: '#FFFFFF',
headerTitleStyle: {
fontFamily: 'Raleway-Regular',
fontWeight: '500',
opacity: 0,
},
}}
/><JobboardStack.Screenname="Job"component={JobScreen}options={{headerTintColor: '#FBF7EF',
}}
/></JobboardStack.Navigator>
);
};
It looks like the issue is caused by the use of the useState hook inside the sharedScreenOptions function, which is being passed as a prop to the createStackNavigator component. This function is being called inside the render method of the component, which means that the hook will be called every time the component is rendered, causing the error that you are seeing.
One way to fix this issue would be to move the sharedScreenOptions function outside of the component, so that it is not called inside the render method. You can then pass the required props to the function as arguments, rather than using the props object.
For example:
export const sharedScreenOptions = (navigation, isOpen, setIsOpen) => { const toggleMenu = () => { setIsOpen(!isOpen); LayoutAnimation.easeInEaseOut(); }; return { headerBackTitleVisible: false, header: (props) => { return ( <><GradientHeader isOpen={isOpen} {...props} /> {isOpen ? ( <TouchableOpacitystyle={{height: Dimensions.get('window').height, width: Dimensions.get('window').width, backgroundColor: 'rgba(42, 44, 65, 0.5)', position: 'absolute', zIndex: -999, }} onPress={() => toggleMenu()}></TouchableOpacity> ) : null} </> ); }, headerRight: () => { return ( <View style={styles.iconContainer}><TouchableOpacity onPress={() => navigation.navigate('Job')}> <MailButton navigation={navigation} /></TouchableOpacity><NotificationButton navigation={navigation} /><TouchableOpacity onPress={() => toggleMenu()}> {isOpen ? <CloseButton /> : <HamburgerButton />} </TouchableOpacity></View> ); }, headerStyle: { backgroundColor: 'transparent', }, }; }; const JobboardStackScreens = () => { const [isOpen, setIsOpen] = useState(false); return ( <JobboardStack.NavigatorinitialRouteName="Jobboard"screenOptions={(props) => sharedScreenOptions(props.navigation, isOpen, setIsOpen)}> <JobboardStack.Screenname="JobBoard"component={JobboardScreen}options={{headerTintColor: '#FFFFFF', headerTitleStyle: { fontFamily: 'Raleway-Regular', fontWeight: '500', opacity: 0, }, }} /><JobboardStack.Screenname="Job"component={JobScreen}options={{headerTintColor: '#FBF7EF', }} /></JobboardStack.Navigator> ); };