Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.

Commit b77e6c0

Browse files
committed
Update README
1 parent 2521400 commit b77e6c0

1 file changed

Lines changed: 120 additions & 3 deletions

File tree

README.md

Lines changed: 120 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
# react-navigation-redux-helpers
22

3-
This repo contains Redux middleware and utils for React Navigation.
3+
This package allows the user to manage their React Navigation state from within Redux.
4+
5+
## How it works
6+
7+
1. Any navigator can be passed a `navigation` prop to turn it into a "controlled" component, which defers state management to its parent. This mechanism is used in React Navigation to nest navigators, but it can also be used to customize state management.
8+
2. A Redux middleware is used so that any events that mutate the navigation state properly trigger React Navigation's event listeners.
9+
3. Finally, a reducer enables React Navigation actions to mutate the Redux state.
10+
11+
## Motivation
12+
13+
Most projects that are using both Redux and React Navigation don't need this library. And passing `navigation` to the root navigator means that you will have to handle state persistance and `BackHandler` behavior yourself. However, there are some things you can do with this library that you can't do without:
14+
15+
1. It's possible to implement [custom actions](https://github.com/Ashoat/squadcal/blob/4ce900481bbfd1681d568edc669b66b1ae9555f0/native/navigation/navigation-setup.js#L384-L395), allowing you to manipulate the navigation state in ways that aren't possible with the stock React Navigation actions. (If you want animations to run on your action, [make sure](https://github.com/Ashoat/squadcal/blob/4ce900481bbfd1681d568edc669b66b1ae9555f0/native/navigation/navigation-setup.js#L633) to set `isTransitioning` to true!)
16+
2. This library allows the user to customize the persistance of their navigation state. For instance, you could choose to persist your navigation state in encrypted storage. Most users don't need this, as there are no practical downsides to handling persistance of navigation state and Redux state separately.
17+
3. You can implement [custom reducer behavior](https://github.com/Ashoat/squadcal/blob/4ce900481bbfd1681d568edc669b66b1ae9555f0/native/navigation/navigation-setup.js#L341-L352) to validate state and maintain consistency between navigation state and other application state.
418

519
## Installation
620

@@ -14,9 +28,60 @@ This repo contains Redux middleware and utils for React Navigation.
1428
npm install --save react-navigation-redux-helpers
1529
```
1630

17-
## Use
31+
## Example
1832

19-
Consult the [React Navigation](https://reactnavigation.org/docs/redux-integration.html) docs for how to use this library.
33+
```js
34+
import {
35+
createStackNavigator,
36+
} from 'react-navigation';
37+
import {
38+
createStore,
39+
applyMiddleware,
40+
combineReducers,
41+
} from 'redux';
42+
import {
43+
reduxifyNavigator,
44+
createReactNavigationReduxMiddleware,
45+
createNavigationReducer,
46+
} from 'react-navigation-redux-helpers';
47+
import { Provider, connect } from 'react-redux';
48+
import React from 'react';
49+
50+
const AppNavigator = createStackNavigator(AppRouteConfigs);
51+
52+
const navReducer = createNavigationReducer(AppNavigator);
53+
const appReducer = combineReducers({
54+
nav: navReducer,
55+
...
56+
});
57+
58+
// Note: createReactNavigationReduxMiddleware must be run before reduxifyNavigator
59+
const middleware = createReactNavigationReduxMiddleware(
60+
"root",
61+
state => state.nav,
62+
);
63+
64+
const App = reduxifyNavigator(AppNavigator, "root");
65+
const mapStateToProps = (state) => ({
66+
state: state.nav,
67+
});
68+
const AppWithNavigationState = connect(mapStateToProps)(App);
69+
70+
const store = createStore(
71+
appReducer,
72+
applyMiddleware(middleware),
73+
);
74+
75+
class Root extends React.Component {
76+
render() {
77+
return (
78+
<Provider store={store}>
79+
<AppWithNavigationState />
80+
</Provider>
81+
);
82+
}
83+
}
84+
```
2085

2186
## API
2287

@@ -58,3 +123,55 @@ function createNavigationReducer(navigator: Navigator): Reducer<*, *>;
58123
* This basically just wraps `navigator.router.getStateForAction`, which you can call directly if you'd prefer.
59124
* Param `navigator` is your root navigator (React component).
60125
* Call this reducer from your master reducer, or combine using `combineReducers`.
126+
127+
## Miscellaneous
128+
129+
### Mocking tests
130+
131+
To make Jest tests work with your React Navigation app, you need to [change the Jest preset](https://jestjs.io/docs/en/tutorial-react-native) in your `package.json`:
132+
133+
```js
134+
"jest": {
135+
"preset": "react-native",
136+
"transformIgnorePatterns": [
137+
"node_modules/(?!(jest-)?react-native|react-navigation|react-navigation-redux-helpers)"
138+
]
139+
}
140+
```
141+
142+
### Back button
143+
144+
Here is a code snippet that demonstrates how the user might handle the hardware back button on platforms like Android:
145+
146+
```js
147+
import React from "react";
148+
import { BackHandler } from "react-native";
149+
import { NavigationActions } from "react-navigation";
150+
151+
/* your other setup code here! this is not a runnable snippet */
152+
153+
class ReduxNavigation extends React.Component {
154+
componentDidMount() {
155+
BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
156+
}
157+
158+
componentWillUnmount() {
159+
BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
160+
}
161+
162+
onBackPress = () => {
163+
const { dispatch, nav } = this.props;
164+
if (nav.index === 0) {
165+
return false;
166+
}
167+
168+
dispatch(NavigationActions.back());
169+
return true;
170+
};
171+
172+
render() {
173+
/* more setup code here! this is not a runnable snippet */
174+
return <AppNavigator navigation={navigation} />;
175+
}
176+
}
177+
```

0 commit comments

Comments
 (0)