How to recognize previous screen name in React-Navigation? - react-native

Now I have 3 screens in my simple App - firstScreen, secondScreen, thirdScreen.
In the firstScreen, there is a button - "Go back to previous screen!".
In the secondScreen and thirdScreen, there is a button - "Go to firstScreen".
When I navigate to firstScreen from second or third screen, how to know previous screen name?
I'd like to show alert in the firstScreen like this - "You are from secondScreen" or "You are from thirdScreen".
Is this possible?

One of the simplest ways I can think about is by passing parameters when navigating like it's described here.
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => {
/* 1. Navigate to the Details route with params */
navigation.navigate('Details', {
itemId: 86,
fromScreen: 'screen 1',
});
}}
/>
</View>
);
}
Hope it helps!

Related

React Navigation 6 - how to close modal from navigation stack

I am trying to close a React Navigation modal from the navigation stack.
Following the official React Navigation documentation navigation.goBack''' is being used within the '''Modal Screen. This successfully closes the modal, but what I would like to achieve is closing the modal by pressing a button in the navigation stack instead of in the screen.
I have tried both of the below functions and although they work as expected in the Screen, they do not work in the stack navigator.
<Button onPress={() => navigation.pop()} title="Dismiss" />
<Button onPress={() => navigation.goBack()} title="Dismiss" />
I get the following error:
undefined is not an object (evaluating 'navigation.goBack')
How can I get the modal to close by pressing a button in the stack navigator?
I think you have misunderstood this Example.
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ fontSize: 30 }}>This is the home screen!</Text>
<Button
onPress={() => navigation.navigate('MyModal')}
title="Open Modal"
/>
</View>
);
}
function ModalScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ fontSize: 30 }}>This is a modal!</Text>
<Button onPress={() => navigation.goBack()} title="Dismiss" />
</View>
);
}
const RootStack = createStackNavigator();
function RootStackScreen() {
return (
<RootStack.Navigator>
<RootStack.Group>
<RootStack.Screen name="Home" component={HomeScreen} />
</RootStack.Group>
<RootStack.Group screenOptions={{ presentation: 'modal' }}>
<RootStack.Screen name="MyModal" component={ModalScreen} />
</RootStack.Group>
</RootStack.Navigator>
);
}
Note:
both HomeScreen and ModalScreen are screen not model of any kind. screenOptions is an object where you define what type of animation you want to see when user navigate to that screen.
when you set screenOptions to model:
The modal behavior slides the screen in from the bottom and allows the
user to swipe down from the top to dismiss it on iOS.
Finally let talk about your error:
undefined is not an object (evaluating 'navigation.goBack')
navigation props will only be available on those screen which are include in your navigation.
so check that screen is present or not where your accessing navigation.goBack

How to display a button at the bottom of a Webview in react-native?

Inside my component (PrivacyPolicy.js), i have a header view, a webview, and a footer view. the webview, depending on the size, gets scrollable. my issue is that the footer view is displayed at the bottom of the screen like if its style was "position: 'absolute'" so it keeps displayed while scrolling. I need to have it after all webview is displayed.
<View style={styles.main_container}>
<View style={styles.header_container}>
...
</View>
<WebView originWhitelist={['*']} source={{ html: privacyPolicyContent }}/>
<View style={styles.footer_container}>
<CheckBox
disabled={false}
value={this.state.isChecked}
onValueChange={(newValue) => this.setState({
isChecked: newValue
})}
style={styles.checkbox}
tintColors={{ true: '#157dfa' }}
/>
<Text style={styles.checkbox_text}>I have read and accept the Privacy Polic</Text>
</View>
</View>
My styles:
const styles = StyleSheet.create({
main_container: {
flex: 1,
paddingHorizontal:'5%'
},
header_container: {
height: scale(90),
flexDirection: 'row',
marginLeft: 10
},
checkbox_container: {
flexDirection: 'row'
},
checkbox: {
marginLeft: -5,
},
checkbox_text: {
marginTop: 8,
fontSize: 10
}
})
I can see few suggestions:
Since your button is a React Native Button => You can show/hide based on the scrollY positions. For that, you need to communicate over the Bridge to dispatch an event accordingly.
As an alternative solution => You can create the button on the Webview its self to have the same functionality.

React-Native: Passing functions in props.navigation.navigate("XYZScreen", myFunction())

in my react-native application, there are two screens. I want to navigate from one screen to another such that if I press a button in the next screen, the first screen should be refreshed using a method doRefreshing() in the first screen.
Example:
const FirstScreen = (props) => {
const doRefreshing = () => {
...
};
return (
<View>
<TouchableOpacity
onPress={()=>props.navigation.navigate("secondScreen",doRefreshing())}
>
</TouchableOpacity>
</View>
);
}
The example code of second screen:
const SecondScreen = (props) => {
const doRefreshingInFirstScreen = () => {
/** What should I do here? */
};
return (
<View>
<Button
onPress={()=>doRefreshingInFirstScreen()}
>
</Button>
</View>
);
}
Can someone please tell me how shall I refresh the first screen when the button in second screen is pressed and call goes to doRefreshingInFirstScreen()? Or what else I can do to refresh the first screen upon clicking the button in the second screen? Will be really grateful for this help. Thanks in advance.
Did you mean this?
Snack
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details', {onRefresh: () => console.log('refreshing...')})}
/>
</View>
);
}
function DetailsScreen(props) {
const { route } = props;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button onPress={route.params.onRefresh} title="Refresh" />
</View>
);
}
React Native re-renders the screen whenever there is state change but this re-rendering will not happen if the screen is not being displayed. As for your scenario, I will suggest using redux to store the values that need to be refreshed from the second screen. Now whenever you go back to the first screen, then if you are reading value from the redux store, it will read the new values for all the variables that needed to be refreshed from the second screen, thus you will have the new values instead of the old ones.

Navigating to cart screen with stack navigation header

I am having a stack navigator that consists of 7 different screens and a cart icon is placed on the every screen header. I want to navigate by pressing that cart icon to the cart screen/page. I tried to put onPress function on the icon and in the header option also but all in vain.
Also, I want to know how the cart system will work.
Below is my single stack navigator screen
<HomeStack.Screen name="EARRINGS" component={Earring}
options={{headerRight:() => <ShoppingCartIcon /> }}
/>
Below is my ShoppingCartIcon code:
const ShoppingCartIcon = () => {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<View style={{position: 'absolute', top: -20, right: 0, width: 70, height: 70, alignItems:"center",justifyContent:"center", zIndex:2000 }}>
<Text style={{fontSize:20,fontWeight:"bold"}}>0</Text>
</View>
<AntDesign name="shoppingcart" color="black" size={24} style={{marginRight:10}} />
</View>
)
}
export default (ShoppingCartIcon)
Please help me.
You can pass the navigation prop like below
<HomeStack.Screen
name="EARRINGS"
component={Earring}
options={({ navigation }) => ({
headerRight: () => (<ShoppingCartIcon navigation={navigation}/> )
})}
/>
And you can use the navigation prop to navigate to any screen you need
const ShoppingCartIcon = ({navigation}) => {
//other code
navigation.navigate('Cartscreen')
}

Navigating to the first component in a stack navigator with params doesn't work

I have a component within a StackNavigator that I always want to pass params to. This doesn't seem to work if my component is the first component loaded in a StackNavigator. Here's some code that illustrates the problem.
I start in component A.
I press the button to navigate to component B.
In the logs you can see that component B is loaded twice. The first time it's loaded without params.
Android SDK built for x86: rendering with: undefined
Android SDK built for x86: rendering with: ►{data:"from A"}
Also if you click the device back button it goes back to the screen with undefined params.
So there are two issues:
I only navigated once, but I have to go back twice to get back to where I was.
My component is loaded with no params even though I navigated with params.
Here's the code running in an expo snack: https://snack.expo.io/#bdzim/navigate-to-tab-from-parent
class A extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="This is A. Press to go to B"
onPress={() => this.props.navigation.navigate(
'B', { data: 'from A' }
)}
/>
</View>
);
}
}
class B extends React.Component {
render() {
console.log('rendering with: ', this.props.navigation.state.params)
let params = JSON.stringify(this.props.navigation.state.params)
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>
params: {params}
</Text>
<Button
title="This is.. B! Press to go to A"
onPress={() => this.props.navigation.navigate('A')}
/>
</View>
);
}
}
const Stacks = StackNavigator({ B })
const Tabs = TabNavigator({ A, Stacks });