React Navigation Integration with Redux
文章目录

React-Navigation Integration with Redux

Stacks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"dependencies": {
"@expo/samples": "2.1.1",
"@shoutem/ui": "0.23.6",
"expo-asset": "~1.1.0",
"expo-constants": "~1.0.2",
"expo-file-system": "~1.1.0",
"expo-font": "~1.1.0",
"na": "0.0.1-dev0",
"prop-types": "15.6.2",
"react-navigation": "^3.0.9",
"react-navigation-redux-helpers": "2.0.9",
"react-navigation/NavigationTestUtils": "3.0.9",
"react-redux": "6.0.0",
"react-test-renderer": "16.7.0",
"redux": "4.0.1"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import React from 'react';
import { Platform } from 'react-native';
import {
createStackNavigator,
createBottomTabNavigator,
} from 'react-navigation';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider, connect } from 'react-redux';
import {
reduxifyNavigator,
createReactNavigationReduxMiddleware,
createNavigationReducer,
} from 'react-navigation-redux-helpers';

import TabBarIcon from '../components/TabBarIcon';
import HomeScreen from '../screens/HomeScreen';
import ScoresScreen from '../screens/ScoresScreen';
import SearchScreen from '../screens/SearchScreen';
import SettingsScreen from '../screens/SettingsScreen';
import Colors from '../constants/Colors';
import Reducers from '../reducers';

/*
const HomeStack = ...
const SearchStack = ...
const ScoresStack = ...
const SettingsStack = ...
*/

/* Step 1: create a navigation object */
const AppNavigator = createBottomTabNavigator(
{
SearchStack,
HomeStack,
ScoresStack,
SettingsStack,
},
{
tabBarOptions: {
style: {
paddingBottom: 5,
},
activeTintColor: Colors.tintColor,
},
}
);

/* Step 2: prepare reducers */
const navReducer = createNavigationReducer(AppNavigator);
const appReducer = combineReducers({
nav: navReducer, // required, handle actions from react-navigation
reducers: Reducers, // optional, this is your reducers
});
const middleware = createReactNavigationReduxMiddleware(
'root',
state => state.nav
);
const App = reduxifyNavigator(AppNavigator, 'root');
const mapStateToProps = state => ({
state: state.nav,
});

const AppWithNavigationState = connect(mapStateToProps)(App);

const store = createStore(appReducer, applyMiddleware(middleware));

/* step 3: create store and wrap with Provider */
class Root extends React.Component {
render() {
return (
<Provider store={store}>
<AppWithNavigationState />
</Provider>
);
}
}

export default () => <Root />;

Then everything for index are done.

Reducers Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const defaultState = {
xxx: 123,
};

const reducer = (state, actionData) => {
let rv = !state ? defaultState : state;

console.log(actionData);

switch (actionData.type) {
/* Action Item Panel */
case 'PANEL_ACTIONITEM_DISPLAY': {
return {
xxx: state.xxx + 1,
};
}
case 'PANEL_ACTIONITEM_FORM_CHANGE': {
break;
}
case 'PANEL_ACTIONNOTE_FORM_CHANGE': {
break;
}
case 'PANEL_ACTIONNOTE_REQUEST': {
break;
}
default: {
return rv;
}
}
};

export default reducer;

Actions Example

1
2
3
export const actionItem_ShowEditPanel = () => ({
type: 'PANEL_ACTIONITEM_DISPLAY',
});

Actual Usage in Container Components

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import React from 'react';
import { ScrollView, StyleSheet, View, TouchableOpacity } from 'react-native';
import { connect } from 'react-redux'

import * as actions from '../actions'

const mapStateToProps = state => state;

const mapDispatchToProps = dispatch => ({
showActionItemEditRow: (action, data) => dispatch(actions.actionItem_ShowEditPanel()),
})

class SearchScreen extends React.Component {
// hide header from react-navigation
static navigationOptions = {
title: null,
header: null,
};

render() {
return (
<Screen>
<TouchableOpacity onPress={this.props.showActionItemEditRow}>
<Row>
<Text>123</Text>
</Row>
</TouchableOpacity>
</Screen>
);
}
}

export default connect(
mapStateToProps,
mapDispatchToProps
)(SearchScreen);