Skip to content

Commit 408f3b8

Browse files
vonovakbrentvatne
authored andcommitted
document changes to state persistence (react-navigation#425)
1 parent 6c6c729 commit 408f3b8

File tree

2 files changed

+62
-20
lines changed

2 files changed

+62
-20
lines changed

docs/state-persistence.md

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,52 @@ This is especially valuable during development because it allows the developer t
1212
1313
## Usage
1414

15-
You can enable persistence for your top-level navigator by rendering it with a `persistenceKey`:
15+
You can enable persistence for your top-level navigator by rendering it with `persistNavigationState` and `loadNavigationState` props:
16+
17+
- `persistNavigationState` is an async function that receives single argument - the navigation state object. The function should persist it.
18+
- `loadNavigationState` is an async function that does the inverse - it should load the persisted navigation state and return a Promise that resolves with the navigation state object. If the function rejects, React Navigation will start as if no state was provided.
1619

1720
```js
1821
const AppNavigator = createStackNavigator({...});
19-
20-
const App = () => <AppNavigator persistenceKey={"NavigationState"} />;
22+
const persistenceKey = "persistenceKey"
23+
const persistNavigationState = async (navState) => {
24+
try {
25+
await AsyncStorage.setItem(persistenceKey, JSON.stringify(navState))
26+
} catch(err) {
27+
// handle the error according to your needs
28+
}
29+
}
30+
const loadNavigationState = async () => {
31+
const jsonString = await AsyncStorage.getItem(persistenceKey)
32+
return JSON.parse(jsonString)
33+
}
34+
35+
const App = () => <AppNavigator persistNavigationState={persistNavigationState} loadNavigationState={loadNavigationState} />;
2136
```
2237

23-
This provided key will be used as the react native `AsyncStorage` key to save the JSON navigation state.
24-
2538
### Development Mode
2639

2740
This feature is particularly useful in development mode. You can enable it selectively using the following approach:
2841

2942
```js
3043
const AppNavigator = createStackNavigator({...});
31-
const navigationPersistenceKey = __DEV__ ? "NavigationStateDEV" : null;
32-
const App = () => <AppNavigator persistenceKey={navigationPersistenceKey} />;
44+
function getPersistenceFunctions() {
45+
return __DEV__ ? {
46+
persistNavigationState: ...,
47+
loadNavigationState: ...,
48+
} : undefined;
49+
}
50+
const App = () => <AppNavigator {...getPersistenceFunctions()} />;
3351
```
3452

3553
### Loading View
3654

37-
Because the state is persisted asynchronously, the app must render an empty/loading view for a moment while the `AsyncStorage` request completes. To customize the loading view that is rendered during this time, you can use the `renderLoadingExperimental` prop:
55+
Because the state is loaded asynchronously, the app must render an empty/loading view for a moment before the `loadNavigationState` function returns. To customize the loading view that is rendered during this time, you can use the `renderLoadingExperimental` prop:
3856

3957
```js
4058
<AppNavigator
41-
persistenceKey={...}
59+
persistNavigationState={...}
60+
loadNavigationState={...}
4261
renderLoadingExperimental={() => <ActivityIndicator />}
4362
/>
4463
```
@@ -47,7 +66,9 @@ Because the state is persisted asynchronously, the app must render an empty/load
4766
4867
## Warning: Serializable State
4968

50-
Each param, route, and navigation state must be fully JSON-serializable for this feature to work. This means that your routes and params must contain no functions, class instances, or recursive data structures.
69+
Each param, route, and navigation state must be fully serializable for this feature to work. Typically, you would serialize the state as a JSON string. This means that your routes and params must contain no functions, class instances, or recursive data structures.
70+
71+
If you need to modify the nav state object, you may do so in the `loadNavigationState` / `persistNavigationState` functions, but note that if your `loadNavigationState` provides an invalid object (an object from which the navigation state cannot be recovered), React Navigation may not be able to handle the situation gracefully.
5172

5273
## Warning: Route/Router definition changes
5374

website/versioned_docs/version-3.x/state-persistence.md

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,52 @@ This is especially valuable during development because it allows the developer t
1313
1414
## Usage
1515

16-
You can enable persistence for your top-level navigator by rendering it with a `persistenceKey`:
16+
You can enable persistence for your top-level navigator by rendering it with `persistNavigationState` and `loadNavigationState` props:
17+
18+
- `persistNavigationState` is an async function that receives single argument - the navigation state object. The function should persist it.
19+
- `loadNavigationState` is an async function that does the inverse - it should load the persisted navigation state and return a Promise that resolves with the navigation state object. If the function rejects, React Navigation will start as if no state was provided.
1720

1821
```js
1922
const AppNavigator = createStackNavigator({...});
20-
21-
const App = () => <AppNavigator persistenceKey={"NavigationState"} />;
23+
const persistenceKey = "persistenceKey"
24+
const persistNavigationState = async (navState) => {
25+
try {
26+
await AsyncStorage.setItem(persistenceKey, JSON.stringify(navState))
27+
} catch(err) {
28+
// handle the error according to your needs
29+
}
30+
}
31+
const loadNavigationState = async () => {
32+
const jsonString = await AsyncStorage.getItem(persistenceKey)
33+
return JSON.parse(jsonString)
34+
}
35+
36+
const App = () => <AppNavigator persistNavigationState={persistNavigationState} loadNavigationState={loadNavigationState} />;
2237
```
2338

24-
This provided key will be used as the react native `AsyncStorage` key to save the JSON navigation state.
25-
2639
### Development Mode
2740

2841
This feature is particularly useful in development mode. You can enable it selectively using the following approach:
2942

3043
```js
3144
const AppNavigator = createStackNavigator({...});
32-
const navigationPersistenceKey = __DEV__ ? "NavigationStateDEV" : null;
33-
const App = () => <AppNavigator persistenceKey={navigationPersistenceKey} />;
45+
function getPersistenceFunctions() {
46+
return __DEV__ ? {
47+
persistNavigationState: ...,
48+
loadNavigationState: ...,
49+
} : undefined;
50+
}
51+
const App = () => <AppNavigator {...getPersistenceFunctions()} />;
3452
```
3553

3654
### Loading View
3755

38-
Because the state is persisted asynchronously, the app must render an empty/loading view for a moment while the `AsyncStorage` request completes. To customize the loading view that is rendered during this time, you can use the `renderLoadingExperimental` prop:
56+
Because the state is loaded asynchronously, the app must render an empty/loading view for a moment before the `loadNavigationState` function returns. To customize the loading view that is rendered during this time, you can use the `renderLoadingExperimental` prop:
3957

4058
```js
4159
<AppNavigator
42-
persistenceKey={...}
60+
persistNavigationState={...}
61+
loadNavigationState={...}
4362
renderLoadingExperimental={() => <ActivityIndicator />}
4463
/>
4564
```
@@ -48,7 +67,9 @@ Because the state is persisted asynchronously, the app must render an empty/load
4867
4968
## Warning: Serializable State
5069

51-
Each param, route, and navigation state must be fully JSON-serializable for this feature to work. This means that your routes and params must contain no functions, class instances, or recursive data structures.
70+
Each param, route, and navigation state must be fully serializable for this feature to work. Typically, you would serialize the state as a JSON string. This means that your routes and params must contain no functions, class instances, or recursive data structures.
71+
72+
If you need to modify the nav state object, you may do so in the `loadNavigationState` / `persistNavigationState` functions, but note that if your `loadNavigationState` provides an invalid object (an object from which the navigation state cannot be recovered), React Navigation may not be able to handle the situation gracefully.
5273

5374
## Warning: Route/Router definition changes
5475

0 commit comments

Comments
 (0)