Skip to content

Commit 34f38ea

Browse files
committed
Add guide for upgrading from 4.x
1 parent 7b5c6e4 commit 34f38ea

File tree

3 files changed

+160
-1
lines changed

3 files changed

+160
-1
lines changed

docs/upgrading-from-4.x.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
id: upgrading-from-4.x
3+
title: Upgrading from 4.x
4+
sidebar_label: Upgrading from 4.x
5+
---
6+
7+
> TODO: This guide is a work in progress. Please send pull requests to improve it.
8+
9+
React Navigation 5 has a completely new component based API. While the main concepts are the same, the API is different. In this guide, we aim to document all the differences so that it's easier to upgrade your app.
10+
11+
You can also use the [compatibility layer](compatibility.md) to reuse code using the old API with minimal changes.
12+
13+
## Configuring the navigator
14+
15+
In React Navigation 4.x, we used to statically configure our navigator to `createXNavigator` functions. The first parameter was an object containing route configuration, and the second parameter was configuration for the navigator.
16+
17+
```js
18+
const RootStack = createStackNavigator(
19+
{
20+
Home: {
21+
screen: HomeScreen,
22+
navigationOptions: { title: 'My app' },
23+
},
24+
Profile: {
25+
screen: ProfileScreen,
26+
params: { user: 'me' },
27+
},
28+
},
29+
{
30+
initialRouteName: 'Home',
31+
defaultNavigationOptions: {
32+
gestureEnabled: false,
33+
},
34+
}
35+
);
36+
```
37+
38+
With 5.x, we now configure the navigator inside a component. First, we create `Navigator` and `Screen` pair using `createXNavigator` and then use them to render our navigator.
39+
40+
There are few key differences here:
41+
42+
- All of the configuration is passed as props to the navigator
43+
- The route configuration is done using `Screen` elements and passed as children
44+
- `params` becomes `initialParams` prop on `Screen`
45+
- `navigationOptions` becomes `options` prop on `Screen`
46+
- `defaultNavigationOptions` becomes `screenOptions` prop on `Navigator`
47+
48+
```js
49+
const Stack = createStackNavigator();
50+
51+
function RootStack() {
52+
return (
53+
<Stack.Navigator
54+
initialRouteName="Home"
55+
screenOptions={{ gestureEnabled: false }}
56+
>
57+
<Stack.Screen
58+
name="Home"
59+
component={HomeScreen}
60+
options={{ title: 'My app' }}
61+
/>
62+
<Stack.Screen
63+
name="Profile"
64+
component={ProfileScreen}
65+
initialParams={{ user: 'me' }}
66+
/>
67+
</Stack.Navigator>
68+
);
69+
}
70+
```
71+
72+
## The `navigation` prop
73+
74+
In React Navigation 4.x, the `navigation` prop contained various helper methods as well as the current screen's state. In React Navigation 5.x, we have split the `navigation` prop into 2 props: `navigation` prop contains helper methods such as `navigate`, `goBack` etc., `route` prop contains the current screen's data (previously accessed via `navigation.state`).
75+
76+
This means, now we can access screen's params through `route.params` instead of `navigation.state.params`:
77+
78+
```js
79+
function ProfileScreen({ route }) {
80+
const useerId = route.params.me;
81+
82+
// ...
83+
}
84+
```
85+
86+
Previously we could also use `navigation.getParam('someParam', 'defaultValue')` to get a param value. It addressed 2 things:
87+
88+
- Guard against `params` being `undefined` in some cases
89+
- Provide a default value if the `params.someParam` was `undefined` or `null`
90+
91+
Now, the same thing can be achieved using the upcoming [optional chaining](https://github.com/tc39/proposal-optional-chaining) and [nullish coalescing](https://github.com/tc39/proposal-nullish-coalescing) operators:
92+
93+
```js
94+
navigation.getParam('someParam', 'defaultValue');
95+
```
96+
97+
is equivalent to:
98+
99+
```js
100+
route.params?.someParam ?? 'defaultValue';
101+
```
102+
103+
Remember to add the Babel plugins for [optional-chaining](https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining) and [nullish-coalescing-operator](https://babeljs.io/docs/en/next/babel-plugin-proposal-nullish-coalescing-operator).
104+
105+
## Specifying `navigationOptions` for a screen
106+
107+
In React Navigation 4.x, we could do the following to specify `navigationOption`:
108+
109+
```js
110+
class ProfileScreen extends React.Component {
111+
static navigationOptions = {
112+
headerShown: false,
113+
};
114+
115+
render() {
116+
// ...
117+
}
118+
}
119+
```
120+
121+
With React Navigation 5.x, we need to pass the configuration when defining the screen:
122+
123+
```js
124+
<Stack.Screen
125+
name="Profile"
126+
component={ProfileScreen}
127+
options={{ headerShown: false }}
128+
/>
129+
```
130+
131+
For dynamic options, the `options` prop also accepts a function which receives the `navigation` and `route` props:
132+
133+
```js
134+
<Stack.Screen
135+
name="Profile"
136+
component={ProfileScreen}
137+
options={({ route }) => ({ title: route.params.user })}
138+
/>
139+
```
140+
141+
In addition to this, React Navigation 5.x has another way to configure screen dynamically based on a screen's props or state by calling `navigation.setOptions`:
142+
143+
```js
144+
function SelectionScreen({ navigation }) {
145+
const [selctionCount, setSelectionCount] = React.useState(0);
146+
147+
navigation.setOptions({
148+
title:
149+
selctionCount === 0 ? 'Select items' : `${selectionCount} items selected`,
150+
});
151+
152+
// ...
153+
}
154+
```

website/i18n/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@
273273
"title": "Type checking with TypeScript",
274274
"sidebar_label": "Type checking with TypeScript"
275275
},
276+
"upgrading-from-4.x": {
277+
"title": "Upgrading from 4.x",
278+
"sidebar_label": "Upgrading from 4.x"
279+
},
276280
"use-focus-effect": {
277281
"title": "useFocusEffect",
278282
"sidebar_label": "useFocusEffect"

website/sidebars.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"localization",
3838
"web-support",
3939
"function-after-focusing-screen",
40-
"react-native-screens"
40+
"react-native-screens",
41+
"upgrading-from-4.x"
4142
],
4243
"Build your own Navigator": [
4344
"routers",

0 commit comments

Comments
 (0)