I am using react native’s createNativeStackNavigator to navigate between two screens, say screen A and Screen B. Each screen have their own states and also each have their own buttons that can change their state. The problem I am facing is when I navigate say from screen A to screen B and I go back to screen A, the states of screen A are reset to their initial state. How can I persist the states of each screen when navigating from one to another?I can do it with asyncstorage, But I was wondering if there is a better way to do it without having to use asyncstorage? for example , in the following two components,when i set isSelected to true, and navigate back to profile screen and come back again to screen setings, the state of isSelected dchanges to its default value.
thank you for you help in advance.
const ProfileStack = createNativeStackNavigator();
const ProfileStackScreen = () => {
return (
<>
<ProfileStack.Navigator initialRouteName = "Profiles">
<ProfileStack.Screen name ="Profiles" component={Profile}/>
<ProfileStack.Screen name="settings" component={Settings}/>
</ProfileStack.Navigator>
</>
)
}
export default ProfileStackScreen
const Settings = ({navigation,route}) => {
const Praise = useCallback(({message,txtclr})=>{
const [isSelected, setSelection] = React.useState(false);
return (
<View style={styles.checkboxcontainer}>
<Switch
value={isSelected}
onValueChange={()=>{
if(message==="DarkMode"){
toggleTheme()
}
setSelection(prev=>!prev)
}}
style={styles.checkbox}
/>
</View>
)
},[])
const CommonComp = ({title}) =>{
return (
<TouchableOpacity style={{margin: 6}}>
<Text style={[styles.txt,{color:txtColr}]}>{title}</Text>
</TouchableOpacity>
)
}
const TogtherComp = ({msg}) =>{
return (
<TouchableOpacity>
<View style={{flexDirection: "row",margin: 6}}>
<Praise txtclr={txtColr} message={msg} />
</View>
</TouchableOpacity>
)
}
return (
<SafeAreaView style={{backgroundColor:bgcolr,flex:1}}>
<ScrollView>
<Text style={[{color:txtColr ,marginTop: 12},styles.txtsH]}>Notification Settings</Text>
<CommonComp title="Followed Users" />
<TogtherComp msg="DarkMode"/>
<CommonComp title="Delete Account"/>
<CommonComp title="Logout" />
</ScrollView>
</SafeAreaView>
)
}
const Profile = ({navigation})=>{
const RowMsg =({title,icnName})=>{
return (
<TouchableOpacity>
<View style={{flexDirection: "row",margin: 6}}>
<Icon style ={styles.ics} name= {icnName}/>
<Text style={[styles.txt,{color:txtColr}]}>{title}</Text>
</View>
</TouchableOpacity>
)
}
const FundPart =({title,icnName}) =>{
return (
<View style={styles.fundsmsg}>
<Icon style={{marginLeft: 18,marginTop: 4,marginRight: 5}} name={icnName}/>
<Text style={{color: txtColr}}>{title}</Text>
</View>
)
}
return (
<SafeAreaView style={{backgroundColor:bgcolr}}>
<View>
<TouchableOpacity onPress={()=>navigation.navigate("settings")}>
<Icon size={18} name="gear" style={{marginLeft: 370,marginTop: 12}}/>
</TouchableOpacity>
</View>
<View>
<Text style={[styles.maintxt,{color:txtColr}]}>Buying and Selling</Text>
<RowMsg icnName="calendar" title="Listings" />
<RowMsg icnName="search" title="Purchases" />
<RowMsg icnName="heart-o" title="Favourites" />
<RowMsg icnName="file-o" title="Aapp savings" />
</View>
</View>
</ScrollView>
</SafeAreaView>
)
}
2
Answers
When using the
navigator.goBack()
function to return to Screen A, the issue of state resetting can be avoided. The state only resets when navigating from Screen B to Screen A. Instead of navigating directly back to Screen A, try using thegoBack()
function to go back to the previous screen. By using this function, not only will the state remain intact, but other properties such as scroll view position will also be preserved. thenavigate(screenName)
function blurs the current component and displays the latest component on top of the navigation stack, it does not destroy the component itself.goBack()
exists inreact-navigation
only. (you need to find the equivalent function in your specific library)To keep the state you can simply do a
goBack()
to navigate back to the previous screen.To share data between screens, there are several ways to do this:
One of them as you mentioned above with AsyncStorage.
You can also pass parameters at the time of navigation and thus share data between the screens
navigation.navigate("settings", { isSelected: true })
You can see more about react navigation params here.
Or you can also use a lib or api that manages global variables, for example, ReactContext, Redux, Zustand, etc…
Generally these libs are more suitable for working with data that will be used in several places in the application
In this case, as it is small data that needs to be shared on just one page, I would use react’s AsyncStorage or context api, they are easy to implement and serve to manage this small and specific data. In a situation with larger data that will be used in different parts of the application, involving business rules and communications with external APIs, I recommend resorting to a lib with redux or zustand. Hope I helped.