react-navigationredux 的使用,这个网上很多.这里介绍下两者的结合使用.

我代码的目录结构是:
react-navigation和redux的目录结构

使用的三方库是:

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
{
"name": "RN_nav",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.3.0-alpha.1",
"react-native": "0.54.0",
"react-navigation": "^1.5.1",
"react-navigation-redux-helpers": "^1.0.3",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-actions": "^2.3.0",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0"
},
"devDependencies": {
"babel-jest": "22.4.1",
"babel-preset-react-native": "4.0.0",
"jest": "22.4.2",
"react-test-renderer": "16.3.0-alpha.1"
},
"jest": {
"preset": "react-native"
}
}

下面是各文件的源码.

App.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/

import React,{ Component } from 'react';
import {Provider} from 'react-redux';
import store from './src/store';
import NavigatorPages from './src/AllPages/TabNavigatorPage';
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<Provider store={store}>
<NavigatorPages/>
</Provider>
);
}
}

Allreducer

store.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

import {createStore,applyMiddleware} from 'redux';
//中间件
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import {
createReduxBoundAddListener,
createReactNavigationReduxMiddleware,
} from 'react-navigation-redux-helpers';

//reducers
import reducers from './Allreducer/index';
//引用react-navigation-redux-helpers组件手动创建中间件,接受state并返回新的state,让路由刷新
// Note: createReactNavigationReduxMiddleware must be run before createReduxBoundAddListener
const middleware = createReactNavigationReduxMiddleware(
"App",
state => state.nav,
);
export const addListener = createReduxBoundAddListener("App");
const middleWares = [middleware,thunk,logger];
export default applyMiddleware(...middleWares)(createStore)(reducers);

FirstPageReducer.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import {handleActions} from 'redux-actions';
const initialState = {
zglNum:0
};
export default handleActions({
ADD:(state,action)=>{
// alert(state.zglNum)
return {
...state,
zglNum:state.zglNum + 1,
secondState:'iOS'
}

},
SUB:(state,action)=>{
return {
...state,
zglNum:state.zglNum - 1,
secondState:'Android'
}

}
},initialState);

SecondPageReducer.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Created by shaotingzhou on 2018/3/6.
*/
import {handleActions} from 'redux-actions';
const initialState = {
xxx:0
};
export default handleActions({
SECOND:(state,action)=>{
return {
...state,
xxx:2
}

},
},initialState);

index.js

1
2
3
4
5
6
7
8
9
10
import { combineReducers } from 'redux';
import TabNavigatorReducer from './TabNavigatorReducer';
import FirstPageReducer from './FirstPageReducer';
import SecondPageReducer from './SecondPageReducer';
const reducers = combineReducers({
TabNavigatorReducer,
FirstPageReducer,
SecondPageReducer,
});
export default reducers;

AllPages

FirstPage.js

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
79
80
81
82
83
84
85
import React, { PureComponent } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Image
} from 'react-native';
import {connect} from 'react-redux';
import {ADD,SUB} from '../Actions/FirstPageActions';

class FirstPage extends PureComponent {

static navigationOptions = {
title:'首页',
};
// componentWillUpdate(){
// alert(this.props.status);
//
// }
// componentDidUpdate(){
// alert(this.props.status);
// }

// ES6 props
// static defaultProps={
// zglNum:0,
// }



render() {
return (
<View style={styles.container}>
<TouchableOpacity
onPress={()=>{
this.props.dispatch(ADD());
}}
>
<Text style={styles.welcome}>
+
</Text>
</TouchableOpacity>

<Text style={styles.welcome}>
{this.props.zglNum}
</Text>

<TouchableOpacity
onPress={()=>{
this.props.dispatch(SUB());
}}
>
<Text style={styles.welcome}>
-
</Text>
</TouchableOpacity>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
textView: {
fontSize: 16,
textAlign: 'center',
margin: 10,
color:'red'
},
});
const mapStateToProps = (store)=>({
zglNum: store.FirstPageReducer.zglNum //数字
});
export default connect(mapStateToProps)(FirstPage);

SecondPage.js

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
import React, { PureComponent } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Image
} from 'react-native';
import {connect} from 'react-redux';
import {SECOND} from '../Actions/SecondPageActions';


class SecondPage extends PureComponent {
static navigationOptions = {
title:'第二'
};

// ES6 props
static defaultProps={
secondState:'默认',
}

render() {
return (
<View style={styles.container} >
<Text onPress={()=>this.onClick()}>{this.props.secondState}</Text>
</View>
);
}

onClick =() =>{
this.props.navigation.navigate('Snnn')
}


}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
textView: {
fontSize: 16,
textAlign: 'center',
margin: 10,
color:'red'
},
});
const mapStateToProps = (store)=>({
secondState:store.FirstPageReducer.secondState
});
export default connect(mapStateToProps)(SecondPage);
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Image
} from 'react-native';
import FirstPage from './FirstPage';
import SecondPage from './SecondPage';
import {connect} from 'react-redux';
import Snnn from './Snnn'
import {
StackNavigator,
addNavigationHelpers,
TabNavigator,
} from 'react-navigation';

import {addListener} from '../store';
class NavigatorPages extends Component{
constructor(props){
super(props);
}
render(){
return(
<SimpleAppNavigator
navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav,
addListener
})}

/>
)
}
}



const Tab = TabNavigator({
page1: {
screen: FirstPage,
navigationOptions: ({ navigation }) => ({
tabBarLabel: '苹果233',
tabBarIcon: ({ focused, tintColor }) => (
<Image
source={focused ? require('../../image/one_selected.png') : require('../../image/one.png')}
style={{ width: 25, height: 25 }}
/>
)
}),
},
page2: {
screen: SecondPage,
navigationOptions: ({ navigation }) => ({
tabBarLabel: '安卓',
tabBarIcon: ({ focused, tintColor }) => (
<Image
source={focused ? require('../../image/two_selected.png') : require('../../image/two.png') }
style={{ width: 25, height: 25 }}
/>
)
}),
},


},{
initialRouteName: 'page1',
swipeEnabled: true,
animationEnabled: true,
tabBarPosition:'bottom',
lazy: false,
tabBarOptions: {
showIcon: true,
activeTintColor: '#979797',
inactiveTintColor: '#979797',
style: { backgroundColor: '#ffffff' },
}
});

export const SimpleAppNavigator = StackNavigator({
Tab: {
screen: Tab,
},
page1 : {
screen: FirstPage,
},
page2 : {
screen: SecondPage
},
Snnn : {
screen: Snnn

}
});




const mapStateToProps = (store)=>({
nav : store.TabNavigatorReducer,
});


export default connect(mapStateToProps)(NavigatorPages);

Actions

ActionsTypes.js

1
2
3
4
5
//Tab1
export const ADD = 'ADD';
export const SUB = 'SUB';

//Tab2

FirstPageActions.js

1
2
3
4
import {createAction} from 'redux-actions';
import * as TYPES from './ActionTypes';
export const ADD = createAction(TYPES.ADD);
export const SUB = createAction(TYPES.SUB);

SccondPageActions.js

1
2
3
4
5
/**
* Created by shaotingzhou on 2018/3/6.
*/
import {createAction} from 'redux-actions';
import * as TYPES from './ActionTypes';

源码
效果图:
reactNavigationRedux.gif

另外:dva+react-navigation
另外:Mbox+react-navigation