react-navigation使用技巧(进阶篇)

转子http://www.jianshu.com/p/b877115fff1b

之前写过react-navigation使用技巧,那篇文章中主要讲了React-navigation的属性,封装和一些小技巧。虽然上篇文章中也有一些小技巧,但因为补充的比较晚,导致有些人没有看全,再加上我又找到了一些新的小玩意,特此写了本篇文章,如果之后还有新发现,也会再这篇文章中更新出来。

如果遇到什么问题可以在评论回复,或者加QQ群397885169询问

1、让TabBar拥有点击事件

感谢群友再遇见分享

官方的api里面是没有提供tabBar的点击事件的,但在开发中经常需要监听tabBar的点击事件,解决这个问题的一种方法就是去修改源码,另一种是监听ontransitionend。(第二种方法这里先不讨论)

源码中一共需要修改8处地方,包含3个js文件。源码在下面。

1、react-navigation目录下src/views/TabView/TabBarBottom.js


TabBarBottom.png

2、react-navigation目录下src/views/TabView/TabBarTop.js


TabBarTop.png

3、react-navigation目录下src/views/TabView/TabView.js


TabView.png

注意:第111行中的getScreenConfig需要手动改成getScreenoptions,要不然修改完源码会报错。

源码在这里,要注意修改getScreenoptions

修改源码之后,在页面中这么用:

static navigationoptions = ({navigation,screenProps}) => ({
    onTabPress:(()=>{
        alert('Home');
    })
});

2、修改页面跳转动画

上一篇文章中,说了怎么将安卓跳转动画改成iOS那样的,但其实react-navigation一共提供了4种跳转动画:
1、从右向左:forHorizontal
2、从下向上:forVertical
3、安卓那种的从下向上:forFadeFromBottomAndroid
4、无动画:forInitial

但因为库的限制,想实现某些页面使用某种动画还是很难的,只能通过Demo中提供的笨方法来实现。

首先还是导入react-navigation中的方法

import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';

如果要改变跳转动画只能在StackNavigator中实现transitionConfig方法

const MainStack = StackNavigator({
    Main:{
        screen:Main,},{
    // mode:'modal',headerMode: 'screen',transitionConfig:()=>({
     // 只要修改最后的forVertical就可以实现不同的动画了。
      screenInterpolator:CardStackStyleInterpolator.forVertical,})
});

3、在Reset方法中传参

react-navigation中的reset方法,应该都不陌生吧,重置路由。但有的需求是在登陆之后,重置路由并传递参数到某个页面,之前一直以为不可以,直到群友的react-native reset方法中传参的写法的这篇文章出现,感谢群友nextChampion的贡献。

const resetAction = NavigationActions.reset({
 index: 0, actions: [
    NavigationActions.navigate({routeName: 'Home',params: { token: '123456' }})
    ]
})

this.props.navigation.dispatch(resetAction);

页面中可以通过如下方法得到参数。

this.props.navigation.state.params.token

4、goBack返回指定页面

在上篇文章中也有这个技巧,这里是总结重发。

react-navigation目录下src/routers/StackRouter.js

if (action.type === NavigationActions.BACK) {
    let backRouteIndex = null;
    if (action.key) {

      const backRoute = state.routes.find(
        /* $FlowFixMe */
        /* 修改源码 */
        route => route.routeName === action.key
        /* (route: *) => route.key === action.key */
      );
      /* $FlowFixMe */
      console.log('backRoute =====',backRoute);
      backRouteIndex = state.routes.indexOf(backRoute);
      console.log('backRoute =====',backRouteIndex);
    }
    if (backRouteIndex == null) {
      return StateUtils.pop(state);
    }
    if (backRouteIndex >= 0) {
      return {
        ...state,routes: state.routes.slice(0,backRouteIndex+1),index: backRouteIndex - 1 + 1,};
    }
  }

注意:这样的修改源码之后,如果项目中使用Redux,并且启用了滑动返回,很会很大几率导致app卡死,所以并不太推荐这种方式,最好使用下面的方式

5、react-navigation集成Redux

可能会有人认为这样集成会麻烦,而且react-navigation内部实现也是类似Redux的高阶函数。我之前也是这么认为的,直到在识兔中,使用Redux修改首页图片之后滑动返回会导致app卡死。

react-navigation集成Redux之后,能获取当前screenkeyrouteNmae等参数,goBack()的时候就可以直接取到key,而不用修改源码啦!

具体操作步骤可以在识兔,一款用来识别图片的开源项目中查看。

如果看不懂下面的修改步骤,可以先看下之前的文章Redux "使用"教程

集成

1、添加addNavigationHelpers

import {
    StackNavigator,TabNavigator,addNavigationHelpers
} from 'react-navigation';

2、首先修改识兔中的App.js的导出方式

const AppWithNavigationState = ({ dispatch,nav }) => (
    <MyApp navigation={addNavigationHelpers({ dispatch,state: nav })}/>
);

const mapStatetoProps = state => ({
    nav: state.nav,});

export default connect(mapStatetoProps)(AppWithNavigationState);

3、创建StackReducer

// MyApp 是在App.js中导出的
import { MyApp } from '../APP';


export default function StackReducer(state,action) {
    let nextState;
    switch (action.type) {
        default:
            nextState = MyApp.router.getStateForAction(action,state);
            break;
    }
    return nextState || state;
}

4、修改rootReducer

import nav from './StackReducer'; const RootReducer = combineReducers({ ...,nav,}); export default RootReducer;import nav from './StackReducer'; const RootReducer = combineReducers({ ...,}); export default RootReducer;

使用

1、修改ShiTu.js

export default connect((state) => {
    ...
    const routes  = state.nav.routes;
    return {
        ...
        routes
    };
},{...})(ShiTu)

2、使用

const {routes} = this.props; // 会有意想不到的惊喜哦! console.log(routes);const {routes} = this.props; // 会有意想不到的惊喜哦! console.log(routes);

感谢群友Roc的提供的react-navigation集成redux脚手架可以通过它快速实现集成Redux

6、安卓返回键在react-navigation中的正常监听

之前使用Navigator的时候,可以通过下面的方法实现监听安卓的返回键,但使用了react-navigation后,会很迷茫,不知该怎么监听了。

解决办法:集成Redux咯!

相关文章

react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接...
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc ...