Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
56 views

Lecture # 18 - React Native Navigations: by Dr. Sidra Sultana

This document discusses navigations in React Native using React Navigation. It explains that React Native does not have a built-in global history stack like web browsers, so React Navigation provides stack navigators to transition between screens and manage navigation history. It provides steps to create a basic stack navigator with multiple screens and navigate between them, as well as methods to navigate back and control the navigation lifecycle.

Uploaded by

Danial Ahmad
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views

Lecture # 18 - React Native Navigations: by Dr. Sidra Sultana

This document discusses navigations in React Native using React Navigation. It explains that React Native does not have a built-in global history stack like web browsers, so React Navigation provides stack navigators to transition between screens and manage navigation history. It provides steps to create a basic stack navigator with multiple screens and navigate between them, as well as methods to navigate back and control the navigation lifecycle.

Uploaded by

Danial Ahmad
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 53

Lecture # 18 – React Native

Navigations
By Dr. Sidra Sultana

1
Hello React Navigation
 In a web browser, you can link to different pages using an
anchor (<a>) tag.
 When the user clicks on a link, the URL is pushed to the
browser history stack.
 When the user presses the back button, the browser pops
the item from the top of the history stack, so the active
page is now the previously visited page.
 React Native doesn't have a built-in idea of a global
history stack like a web browser does -- this is where
React Navigation enters the story.

2
Hello React Navigation cont’d
 React Navigation's stack navigator provides a way for
your app to transition between screens and manage
navigation history.
 If your app uses only one stack navigator then it is
conceptually similar to how a web browser handles
navigation state - your app pushes and pops items from
the navigation stack as users interact with it, and this
results in the user seeing different screens.

3
Creating a stack navigator
 First install react-navigation-stack
 createStackNavigator is a function that returns a React
component.
 It takes a route configuration object and, optionally, an
options object. 
 createAppContainer is a function that returns a React
component to take as a parameter the React component
created by the createStackNavigator, and can be directly
exported from App.js to be used as our App's root
component.

4
Creating a stack navigator cont’d
 import React from 'react';
 import { View, Text } from 'react-native';
 import { createAppContainer } from 'react-navigation';
 import { createStackNavigator } from 'react-navigation-stack';
 class HomeScreen extends React.Component {
 render() {
 return (
 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Home
Screen</Text> </View>
 );
 }
 }
 const AppNavigator = createStackNavigator({ Home: { screen:
HomeScreen, }, });
 export default createAppContainer(AppNavigator);

5
Creating a stack navigator cont’d
 In React Native, the component exported from App.js is the
entry point (or root component) for your app
 it is the component from which every other component descends.
 It's often useful to have more control over the component at
the root of your app than you would get from exporting the
result of createAppContainer.
 So let's export a component that just renders
our AppNavigator stack navigator.
 const AppContainer = createAppContainer(AppNavigator);
 export default class App extends React.Component {
 render() { return <AppContainer />; } }

6
Route configuration shorthand
 Given that the only route configuration we have
for Home is the screen component, we don't need to use
the { screen: HomeScreen } configuration format, we can
use the screen component directly.
 const AppNavigator = createStackNavigator(
 { Home: HomeScreen, });

7
Adding a second route
 The <AppContainer /> component doesn't accept any
props -- all configuration is specified in
the options parameter to
the AppNavigator createStackNavigator function.
 We left the options blank, so it just uses the default
configuration.
 To see an example of using the options object, we will add
a second screen to the stack navigator.

8
Adding a second route cont’d
 // Other code for HomeScreen here...
 class DetailsScreen extends React.Component {
 render() {
 return (
 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
 <Text>Details Screen</Text> </View> );
 }
 }
 const AppNavigator = createStackNavigator( {
 Home: HomeScreen,
 Details: DetailsScreen, },
 { initialRouteName: 'Home', }
 );
 // Other code for App component here...

9
Adding a second route cont’d
 Now our stack has two routes, a Home route and
a Details route.
 The Home route corresponds to
the HomeScreen component, and the Details route
corresponds to the DetailsScreen component.
 The initial route for the stack is the Home route.
 The natural question at this point is: "how do I go from
the Home route to the Details route?".

10
Moving between screens
 If this was a web browser, we'd be able to write something
like this:
 <a href="details.html">Go to Details</a>
 Another way to write this would be:
 <a onClick={() => { document.location.href =
"details.html"; }}>Go to Details</a>
 We'll do something similar to the latter, but rather than
using a document global we'll use the navigation prop that
is passed down to our screen components.

11
Navigating to a new screen
 import * as React from 'react';
 import { Button, View, Text } from 'react-native';
 import { createAppContainer } from 'react-navigation';
 import { createStackNavigator } from 'react-navigation-stack';
 class HomeScreen extends React.Component {
 render() {
 return (
 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
 <Text>Home Screen</Text>
 <Button title="Go to Details" onPress={() =>
this.props.navigation.navigate('Details')} />
 </View> );
 }
 } // ... other code from the previous section
12
Navigating to a new screen cont’d
 Let's break this down:
 this.props.navigation: the navigation prop is passed in to
every screen component in stack navigator
 navigate('Details'): we call the navigate function (on
the navigation prop — naming is hard!) with the name of the route
that we'd like to move the user to.
 If we call this.props.navigation.navigate with a route name that
we haven't defined on a stack navigator, nothing will happen.
 Said another way, we can only navigate to routes that have
been defined on our stack navigator — we cannot navigate to
an arbitrary component.

13
Navigate to a route multiple times
 class DetailsScreen extends React.Component {
 render() {
 return (
 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
 <Text>Details Screen</Text>
 <Button title="Go to Details... again" onPress={() =>
this.props.navigation.navigate('Details')} />
 </View> );
 }
 }
 What will happen?

14
Navigate to a route multiple times cont’d
 Let's suppose that we actually want to add another details screen.
 This is pretty common in cases where you pass in some unique data
to each route (more on that later when we talk about params!).
 To do this, we can change navigate to push.
 This allows us to express the intent to add another route regardless
of the existing navigation history.
 <Button title="Go to Details... again" onPress={() =>
this.props.navigation.push('Details')} />
 Each time you call push we add a new route to the navigation stack.
 When you call navigate it first tries to find an existing route with
that name, and only pushes a new route if there isn't yet one on the
stack.

15
Going back
 The header provided by stack navigator will automatically
include a back button when it is possible to go back from
the active screen (if there is only one screen in the
navigation stack, there is nothing that you can go back to,
and so there is no back button).
 Sometimes you'll want to be able to programmatically
trigger this behavior, and for that you can
use this.props.navigation.goBack();.

16
Going back cont’d
 class DetailsScreen extends React.Component {
 render() {
 return (
 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
 <Text>Details Screen</Text>
 <Button title="Go to Details... again" onPress={() =>
this.props.navigation.push('Details')} />
 <Button title="Go to Home" onPress={() =>
this.props.navigation.navigate('Home')} />
 <Button title="Go back" onPress={() => this.props.navigation.goBack()} />
 </View>
 );
 }
 }

17
Going back cont’d
 Another common requirement is to be able to go
back multiple screens -- for example, if you are several
screens deep in a stack and want to dismiss all of them to
go back to the first screen.
 In this case, we know that we want to go back to Home so
we can use navigate('Home') (not push! try that out and
see the difference).
 Another alternative would be navigation.popToTop(),
which goes back to the first screen in the stack.

18
Navigation lifecycle
 An important question in this context is: what happens
with Home when we navigate away from it, or when we come back
to it? How does a route find out that a user is leaving it or coming
back to it?
 Coming to React Navigation from the web, you may assume that
when user navigates from route A to route B, A will unmount and
its componentWillUnmount will be called.
 You may also expect A will remount again when user comes back
to it.
 While these React lifecycle methods are still valid and are used in
React Navigation, their usage differs from the web.
 This is driven by more complex needs of mobile navigation.

19
Example scenario
 Consider a stack navigator with screens A and B.
 After navigating to A, its componentDidMount is called.
 When pushing B, its componentDidMount is also called,
but A remains mounted on the stack and
its componentWillUnmount is therefore not called.
 When going back
from B to A, componentWillUnmount of B is called,
but componentDidMount of A is not because A remained
mounted the whole time.

20
Passing parameters to routes
 Now that we know how to 
create a stack navigator with some routes and 
navigate between those routes, let's look at how we can
pass data to routes when we navigate to them.
 There are two pieces to this:
 Pass params to a route by putting them in an object as a second
parameter to
the navigation.navigate function: this.props.navigation.navigate
('RouteName', { /* params go here */ })
 Read the params in your screen
component: this.props.navigation.getParam(paramName,
defaultValue).

21
HomeScreen
 class HomeScreen extends React.Component {
 render() {
 return (
 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
 <Text>Home Screen</Text>
 <Button title="Go to Details" onPress={() =>
{ this.props.navigation.navigate('Details', { itemId: 86, otherParam: 'anything
you want here', }); }} />
 </View>
 );
 }
 }

22
DetailsScreen
 class DetailsScreen extends React.Component {
 render() {
 const { navigation } = this.props;
 return (
 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
 <Text>Details Screen</Text>
 <Text> itemId: {JSON.stringify(navigation.getParam('itemId', 'NO-ID'))} </Text>
 <Text> otherParam: {JSON.stringify(navigation.getParam('otherParam', 'default
value'))} </Text>
 <Button title="Go to Details... again" onPress={() => navigation.push('Details',
{ itemId: Math.floor(Math.random() * 100), }) } />
 </View>
 );
 }
 }
23
Passing parameters to routes
 You can also directly access the params object
with this.props.navigation.state.params.
 This may be null if no params were supplied, and so it's
usually easier to just use getParam so you don't have to
deal with that case.
 If you want to access the params directly through props
(eg. this.props.itemId) rather
than this.props.navigation.getParam, you may use a
community-developed react-navigation-props-mapper
 package.

24
Configuring the header bar
 A screen component can have a static property
called navigationOptions which is either an object or a
function that returns an object that contains various
configuration options. The one we use for the header title
is title, as demonstrated in the following example.

25
Setting the header title
 class HomeScreen extends React.Component {
 static navigationOptions = { title: 'Home', };
 /* render function, etc */
 }
 class DetailsScreen extends React.Component {
 static navigationOptions = { title: 'Details', };
 /* render function, etc */
 }

26
Using params in the title
 In order to use params in the title, we need to make navigationOptions a
function that returns a configuration object.
 It might be tempting to try to use this.props inside of navigationOptions,
but because it is a static property of the component, this does not refer to
an instance of the component and therefore no props are available.
 Instead, if we make navigationOptions a function then React Navigation
will call it with an object containing { navigation, navigationOptions,
screenProps } -- in this case, all we care about is navigation, which is the
same object that is passed to your screen props as this.props.navigation.
 You may recall that we can get the params
from navigation through navigation.getParam or navigation.state.params
, and so we do this below to extract a param and use it as a title.

27
Using params in the title cont’d
 class DetailsScreen extends React.Component {
 static navigationOptions = ({ navigation }) => {
 return {
 title: navigation.getParam('otherParam', 'A Nested Details Screen'),
 };
 };
 /* render function, etc */
 }

28
Using params in the title cont’d
 The argument that is passed in to
the navigationOptions function is an object with the
following properties:
 navigation - The navigation prop for the screen, with the
screen's route at navigation.state.
 screenProps - The props passing from above the navigator
component
 navigationOptions - The default or previous options that
would be used if new values are not provided
 We only needed the navigation prop in the above example but
you may in some cases want to
use screenProps or navigationOptions.
29
Updating navigationOptions with setPara
ms
 It's often necessary to update
the navigationOptions configuration for the active screen
from the mounted screen component itself. We can do this
using this.props.navigation.setParams
 /* Inside of render() */
 <Button title="Update the title" onPress={() =>
this.props.navigation.setParams({ otherParam: 'Updated!'
})} />

30
Adjusting header styles
 There are three key properties to use when customizing the
style of your header: headerStyle, headerTintColor,
and headerTitleStyle.
 headerStyle: a style object that will be applied to the View that
wraps the header. If you set backgroundColor on it, that will be
the color of your header.
 headerTintColor: the back button and title both use this property
as their color. In the example below, we set the tint color to
white (#fff) so the back button and the header title would be
white.
 headerTitleStyle: if we want to customize
the fontFamily, fontWeight and other Text style properties for
the title, we can use this to do it.
31
Adjusting header styles cont’d
 class HomeScreen extends React.Component {
 static navigationOptions = {
 title: 'Home',
 headerStyle: { backgroundColor: '#f4511e', },
 headerTintColor: '#fff',
 headerTitleStyle: { fontWeight: 'bold', },
 };
 /* render function, etc */
 }

32
Header buttons
 The most common way to interact with a header is by tapping
on a button either to the left or the right of the title. Let's add a
button to the right side of the header (one of the most difficult
places to touch on your entire screen, depending on finger and
phone size, but also a normal place to put buttons).
 class HomeScreen extends React.Component {
 static navigationOptions = {
 headerTitle: () => <LogoTitle />,
 headerRight: () => ( <Button onPress={() => alert('This is a button!')}
title="Info" color="#fff" /> ),
 };
 }

33
Adding a button to the header
 The binding of this in navigationOptions is not the HomeScreen instance, so
you can't call setState or any instance methods on it. This is pretty important
because it's extremely common to want the buttons in your header to interact
with the screen that the header belongs to. So, we will look how to do this
next.

34
Header interaction with its screen
component
 The most commonly used pattern for giving a header button access to a
function on the component instance is to use params. class HomeScreen
extends React.Component {
 static navigationOptions = ({ navigation }) => {
 return {
 headerTitle: () => <LogoTitle />,
 headerRight: () => ( <Button onPress={navigation.getParam('increaseCount')} title="+1"
color="#fff" /> ),
 };
 };
 componentDidMount() {
 this.props.navigation.setParams({
 increaseCount: this._increaseCount }); }
 state = { count: 0, };
 _increaseCount = () => { this.setState({ count: this.state.count + 1 }); };
 /* later in the render function we display the count */ }

35
App containers
 We've been taking createAppContainer for granted so far,
so let's explain them quickly.
 Containers are responsible for managing your app state
and linking your top-level navigator to the app
environment.
 On Android, the app container uses the Linking API to
handle the back button.
 The container can also be configured to persist your
navigation state.
 On web, you'd use different containers than React Native.

36
App containers cont’d
 As we've seen already, app container usage looks like this:
 import { createAppContainer } from 'react-navigation';
 import { createStackNavigator } from 'react-navigation-
stack';
 const RootStack = createStackNavigator({ /* your routes
here */ });
 const AppContainer = createAppContainer(RootStack);
 // Now AppContainer is the main component for React to
render export default AppContainer;

37
Props of createAppContainer on React
Native
 There are a couple of props worth knowing about on the
app container.
 <AppContainer
onNavigationStateChange={handleNavigationChange}
uriPrefix="/app" />

38
onNavigationStateChange(prevState,
newState, action)
 Function that gets called every time navigation state
managed by the navigator changes. It receives the
previous state, the new state of the navigation and the
action that issued state change. By default it prints state
changes to the console.
 uriPrefix
 The prefix of the URIs that the app might handle. This will be
used when handling a deep link to extract the path passed to the
router.

39
Calling dispatch or navigate on a
container ref
 In some cases you may want to perform navigation actions from the root
of your app, outside of any of the screens. To do this you can use a React 
ref to call the dispatch method on it:
 const AppContainer = createAppContainer(AppNavigator);
 class App extends React.Component {
 someEvent() {
 // call navigate for AppNavigator here:
 this.navigator && this.navigator.dispatch( NavigationActions.navigate({ routeName:
someRouteName }) );
 }
 render() {
 return ( <AppContainer ref={nav => { this.navigator = nav; }} /> );
 }
 }

40
Opening a full-screen modal
 A modal displays content that temporarily blocks interactions
with the main view
 This sounds about right.
 A modal is like a popup — it's not part of your primary
navigation flow — it usually has a different transition, a
different way to dismiss it, and is intended to focus on one
particular piece of content or interaction.
 The purpose of explaining this as part of the React Navigation
fundamentals is not only because this is a common use case, but
also because the implementation requires knowledge of nesting
navigators, which is an important part of React Navigation.

41
Creating a modal stack
 class HomeScreen extends React.Component {
 static navigationOptions = ({ navigation }) => {
 const params = navigation.state.params || {};
 return {
 headerLeft: () => ( <Button onPress={() =>
navigation.navigate('MyModal')} title="Info" color="#fff" /> ),
 /* the rest of this config is unchanged */
 };
 };
 /* render function, etc */
 }

42
Creating a modal stack cnt’d
 class ModalScreen extends React.Component {
 render() {
 return (
 <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
 <Text style={{ fontSize: 30 }}>This is a modal!</Text>
 <Button onPress={() => this.props.navigation.goBack()} title="Dismiss“/?
 </View>
 );
 }
 }

43
Creating a modal stack cnt’d
 const MainStack = createStackNavigator( {
 Home: { screen: HomeScreen, },
 Details: { screen: DetailsScreen, },
 },
 { /* Same configuration as before */ } );

44
Creating a modal stack cnt’d
 const RootStack = createStackNavigator( {
 Main: { screen: MainStack, },
 MyModal: { screen: ModalScreen, },
 },
 { mode: 'modal', headerMode: 'none', }
 );

45
Some important things to notice:
 As we know, the stack navigator function returns a React component
(remember we render <RootStack /> in our App component).
 This same component can be used as a screen component!
 By doing this, we are nesting a stack navigator inside of another
stack navigator.
 In this case, this is useful for us because we want to use a different
transition style for the modal, and we want to disable the header
across the entire stack.
 In the future this will be important because for tab navigation, for
example, each tab will likely have its own stack!
 Intuitively, this is what you expect: when you are on tab A and switch
to tab B, you would like tab A to maintain its navigation state as you
continue to explore tab B.

46
Some important things to notice cont’d:
 The mode configuration for stack navigator can be
either card (default) or modal.
 The modal behavior slides the screen in from the bottom on iOS
and allows the user to swipe down from the top to dismiss it.
 The modal configuration has no effect on Android because full-
screen modals don't have any different transition behavior on the
platform.
 When we call navigate we don't have to specify anything except
the route that we'd like to navigate to.
 There is no need to qualify which stack it belongs to (the
arbitrarily named 'root' or the 'main' stack) — React Navigation
attempts to find the route on the closest navigator and then
performs the action there.
47
Summary
 React Native doesn't have a built-in API for navigation like a
web browser does. React Navigation provides this for you, along
with the iOS and Android gestures and animations to transition
between screens.
 createStackNavigator is a function that takes a route
configuration object and an options object and returns a React
component.
 The keys in the route configuration object are the route names
and the values are the configuration for that route. The only
required property on the configuration is the screen (the
component to use for the route).
 To specify what the initial route in a stack is, provide
an initialRouteName on the stack options object.
48
Summary cont’d
 this.props.navigation.navigate('RouteName') pushes a new route to the
stack navigator if it's not already in the stack, otherwise it jumps to that
screen.
 We can call this.props.navigation.push('RouteName') as many times as
we like and it will continue pushing routes.
 The header bar will automatically show a back button, but you can
programmatically go back by calling this.props.navigation.goBack(). On
Android, the hardware back button just works as expected.
 You can go back to an existing screen in the stack
with this.props.navigation.navigate('RouteName'), and you can go back
to the first screen in the stack with this.props.navigation.popToTop().
 The navigation prop is available to all screen components (components
defined as screens in route configuration and rendered by React
Navigation as a route).

49
Summary cont’d
 While Reacts lifecycle methods are still valid, React Navigation
adds more lifecycle events that you can subscribe to through
the navigation prop.
 You may also use the withNavigationFocus HOC
or <NavigationEvents /> component to react to lifecycle changes.
 navigate and push accept an optional second argument to let you
pass parameters to the route you are navigating to. For
example: this.props.navigation.navigate('RouteName',
{paramName: 'value'}).
 You can read the params through this.props.navigation.getParam
 As an alternative to getParam, you may
use this.props.navigation.state.params. It is null if no parameters
are specified.
50
Summary cont’d
 You can customize the header inside of
the navigationOptions static property on your screen
components.
 The navigationOptions static property can be an object or a
function.
 When it is a function, it is provided with an object with
the navigation prop, screenProps, and navigationOptions on
it.
 You can also specify shared navigationOptions in the stack
navigator configuration when you initialize it.
 The static property takes precedence over that configuration.

51
Summary cont’d
 You can set buttons in the header through
the headerLeft and headerRight properties
in navigationOptions.
 The back button is fully customizable with headerLeft, but
if you just want to change the title or image, there are
other navigationOptions for that
— headerBackTitle, headerTruncatedBackTitle,
and headerBackImage.

52
Summary cont’d
 To change the type of transition on a stack navigator you
can use the mode configuration. When set to modal, all
screens animate-in from bottom to top rather than right to
left. This applies to that entire stack navigator, so to use
right to left transitions on other screens, we add another
navigation stack with the default configuration.
 this.props.navigation.navigate traverses up the navigator
tree to find a navigator that can handle the navigate action.

53

You might also like