import { useIsFocused } from "@react-navigation/native";
import { useRouter } from "expo-router";
import React, { useEffect, useState } from "react";
import { Alert, Modal, StyleSheet, Text, Pressable, View } from "react-native";
import { SafeAreaView, SafeAreaProvider } from "react-native-safe-area-context";
const TestingScreen = () => {
const [modalVisible, setModalVisible] = useState(false);
const route = useRouter();
const isFocused = useIsFocused();
useEffect(() => {
if (isFocused && modalVisible) {
setModalVisible(true);
}
}, [isFocused]);
return (
<SafeAreaProvider>
<SafeAreaView style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text onPress={() => route.navigate("/user/user-profile")}>
go to user-profile
</Text>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</Pressable>
</View>
</View>
</Modal>
<Pressable
style={[styles.button, styles.buttonOpen]}
onPress={() => setModalVisible(true)}
>
<Text style={styles.textStyle}>Show Modal</Text>
</Pressable>
</SafeAreaView>
</SafeAreaProvider>
);
};
//screen to navigate and return
import { useRouter } from "expo-router";
import { View, Text,} from "react-native";
export default function UserProfile() {
const route = useRouter();
return (
<View style={{ flex: 1, padding: 40 }}>
<Text onPress={()=>route.back()}>testing screen</Text>
</View>
);
}
I have tried using useFocused or useFocusEffect for when the state of the modal changes but what happens is that when I return from the screen, the modal simply disappears and does not allow me to open it again, what can I do?
2
Answers
My solution:
Call the modal inside the main modal
Apply animations to make it more attractive
This is a great question.
If I understand, you leave the testing screen and then return after navigating to another component.
In react, when you navigate to a new URL, the component you started in is trashed, therefore, all of the state is lost.
So when the following action is performed, the state variables you have stored are lost:
To fix this issue, you have a couple options:
1. Using redux to manage modal open state:
If you already use redux, moving your ‘modalVisible’ state variable to a slice would be very easy. However, this is a heavy-handed approach and is not recommended for this problem.
2. Rendering the login component conditionally instead of navigating to a different page
This solution has the benefit of maintaining the state variables because instead of changing your href and causing a re-render, you simply change what you are showing and stay on the same URL.
Admittedly, this solution can lead to hard-to-read code, so I would recommend using this sparingly.
See inline conditionals for more info: Conditional Rendering React Docs
3. Using contexts
Contexts are a way to pass data down to all child components without specifying a prop. This approach would work for what you need but would definitely require some refactoring. See the React Docs on contexts for more information.
Hope this helps!!