react native里react-navigation与redux + react-navigation-redux-helpers插件整合方法及样例代码

react-navigation与redux + react-navigation-redux-helpers插件整合方法

以前也做react-navigation与redux的整合,不过那时候react native以及react-navigation的版本都不高,前些天在做新项目时用的是rn0.54版本,react-navigation是1.3.0版本,当我按照低版本的方法进行整合时缺报错了,让我措不及防,踩过的坑还要再踩一遍...

相信大家对于redux都很熟悉,不再介绍有关redux的知识

报错如下:


整合错误代码如下:

<SimpleAppNavigator
    navigation={addNavigationHelpers({
        dispatch: this.props.dispatch,
        state: this.props.nav,
    })}
/>

最后查看react-navigation源码发现原来createNavigationContainer.js文件里的render方法里多出了一个addListener属性,源码如下:

react-navigation 1.0.0-beta.11版本   react native 0.46版本

render() {
  let navigation = this.props.navigation;
  if (this._isStateful()) {
    if (!this._navigation || this._navigation.state !== this.state.nav) {
      this._navigation = addNavigationHelpers({
        dispatch: this.dispatch,
        state: this.state.nav,
      });
    }
    navigation = this._navigation;
  }
  return <Component {...this.props} navigation={navigation} />;
}
react-navigation 1.3.0版本   react native 0.54版本

render() {
  let navigation = this.props.navigation;
  if (this._isStateful()) {
    const nav = this.state.nav;
    invariant(nav, 'should be set in constructor if stateful');
    if (!this._navigation || this._navigation.state !== nav) {
      this._navigation = addNavigationHelpers({
        dispatch: this.dispatch,
        state: nav,
        addListener: (eventName, handler) => {
          if (eventName !== 'action') {
            return { remove: () => {} };
          }
          this._actionEventSubscribers.add(handler);
          return {
            remove: () => {
              this._actionEventSubscribers.delete(handler);
            },
          };
        },
      });
    }
    navigation = this._navigation;
  }
  invariant(navigation, 'failed to get navigation');
  return <Component {...this.props} navigation={navigation} />;
}

好了,已经知道原因了,不过再加上addListener属性后还是会报错,下面介绍具体做法:

1. 需要引用 react-navigation-redux-helpers中间插件,安装命令如下:

   npm install react-navigation-redux-helpers --save

2. 

import {
    createReduxBoundAddListener,
    createReactNavigationReduxMiddleware,
} from 'react-navigation-redux-helpers';

createReduxBoundAddListener: 创建监听器

createReactNavigationReduxMiddleware: 创建中间件

特别注意: createReactNavigationReduxMiddleware 一定要在运行createReduxBoundAddListener之前运行

附上代码:

// Note: createReactNavigationReduxMiddleware must be run before createReduxBoundAddListener
const middleware = createReactNavigationReduxMiddleware(
    "App",
    state => state.nav,
);
export const addListener = createReduxBoundAddListener("App");
const middleWares = [middleware];
export default applyMiddleware(...middleWares)(createStore)(reducers);


最后附上所有页面的详细代码,粘贴复制按照目录结构放置即可运行,运行前请安装相关组件

附上目录结构:


App.js

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>
        );
    }
}

store.js

import {createStore,applyMiddleware} from 'redux';
import {
    createReduxBoundAddListener,
    createReactNavigationReduxMiddleware,
} from 'react-navigation-redux-helpers';

//reducers
import reducers from './Allreducer/index';
// Note: createReactNavigationReduxMiddleware must be run before createReduxBoundAddListener
const middleware = createReactNavigationReduxMiddleware(
    "App",
    state => state.nav,
);
export const addListener = createReduxBoundAddListener("App");
const middleWares = [middleware];
export default applyMiddleware(...middleWares)(createStore)(reducers);


AllPages/TabNavigatorPage.js

import React, { Component } from 'react';
import FirstPage from './FirstPage';
import SecondPage from './SecondPage';
import ThirdPage from './ThirdPage';
import FourthPage from './FourthPage';
import {connect} from 'react-redux';
import {
    TabNavigator,
    addNavigationHelpers,
} from 'react-navigation';
import {addListener} from '../store';
class NavigatorPages extends Component{
    constructor(props){
        super(props);
    }
    render(){
        alert(this.props.nav.index);
        return(
            <SimpleAppNavigator
                navigation={addNavigationHelpers({
                    dispatch: this.props.dispatch,
                    state: this.props.nav,
                    addListener
                })}
            />
        )
    }
}
export const SimpleAppNavigator = TabNavigator({
    page1: {screen: FirstPage},
    page2: {screen: SecondPage},
    page3: {screen: ThirdPage},
    page4: {screen: FourthPage}
},{
    initialRouteName: 'page1',
    swipeEnabled: true,
    animationEnabled: true,
    lazy: false,
    tabBarPosition:'bottom',
});
const mapStateToProps = (store)=>({
    nav : store.TabNavigatorReducer,
});
export default connect(mapStateToProps)(NavigatorPages);

AllReducer/TabNavigatorReducer.js

import {SimpleAppNavigator} from '../AllPages/TabNavigatorPage';
export  default (state,action)=>{
    //获取并返回新的state
    var newState = SimpleAppNavigator.router.getStateForAction(action,state) ;
    return newState || state;
}

AllReducer/index.js

import { combineReducers } from 'redux';
import TabNavigatorReducer from './TabNavigatorReducer';
const reducers = combineReducers({
    TabNavigatorReducer
});
export default  reducers;

下面那四个路由页面可自行创建,都是很简单的页面,不过下面还是给出代码

AllPages/FirstPage.js

import React, { Component } from 'react';
import {
    StyleSheet,
    Text,
    View,
} from 'react-native';
export default class SecondPage extends Component {
    static navigationOptions = {
        tabBarLabel: '页面1',
        //drawerLabel:'页面1'
    };
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    This is First Page!
                </Text>
            </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'
    },
});

AllPages/SecondPage.js

import React, { Component } from 'react';
import {
    StyleSheet,
    Text,
    View,
} from 'react-native';
export default class SecondPage extends Component<Props> {
    static navigationOptions = {
        tabBarLabel: '页面2',
        //drawerLabel:'页面2'
    };
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    This is Second Page!
                </Text>
            </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'
    },
});

AllPages/ThirdPage.js

import React, { Component } from 'react';
import {
    StyleSheet,
    Text,
    View,
} from 'react-native';
export default class ThirdPage extends Component<Props> {
    static navigationOptions = {
        tabBarLabel: '页面3',
        //drawerLabel:'页面3'
    };
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    This is Third Page!
                </Text>
            </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'
    },
});

AllPages/FourthPages.js

import React, { Component } from 'react';
import {
    StyleSheet,
    Text,
    View,
} from 'react-native';
export default class FourthPage extends Component<Props> {
    static navigationOptions = {
        tabBarLabel: '页面4',
        //drawerLabel:'页面4'
    };
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    This is Fourth Page!
                </Text>
            </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'
    },
});

附上运行效果:

  

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值