react-navigation 新增 goBackWithRouteName方法

96
nextChallenger
2017.06.21 16:52* 字数 699

react-navigation是0.45版本新出的路由组件,功能强大.但是在使用过程中发现一个局限性,可以使用navigate('aaa'),通过routeName跳转指定页面,午饭实现goBack('aaa')方法返回到指定页面.

和交流群里一些大神交流了一些看法,兔神选择了修改goBack()方法的源码的方式,实现跳转指定页面.兔神文章链接react-navigation使用技巧.该方法很好很强大,修改内容很少,个人仅仅是出于多想一种解决方法的出发点,尝试另一种方法来解决.

所以我选择了给react-navigation增加新方法goBackWithRouteName(routeName)的方式来实现.下面介绍一下详细的实现过程:

先来一张效果图


首先找到项目中该目录 /node_modules/react-navigation/src/

涉及4个文件:

1. /node_modules/react-navigation/src/addNavigationHelpers.js文件

2. /node_modules/react-navigation/src/addNavigationActions.js文件

3. /node_modules/react-navigation/src/typeDefinition.js文件

4. /node_modules/react-navigation/src/routers/StackRouter.js文件

修改内容

1.addNavigationHelpers.js文件

第18行

goBack: (key?: ?string): boolean =>

navigation.dispatch(

NavigationActions.back({

key: key === undefined ? navigation.state.key : key,

})

),

/*新增代码部分*/

goBackWithRouteName: (routeName?: ?string): boolean =>

navigation.dispatch(

NavigationActions.backWithRouteName({

routeName: routeName === undefined ? navigation.state.routeName : routeName,

})

),

2. addNavigationHelpers.js文件

第7行

const BACK = 'Navigation/BACK';

/*新增代码部分*/

const BACK_WITH_ROUTE_RNAME = 'Navigation/BACK_WITH_ROUTE_RNAME';


第22行

const back = createAction(BACK);

/*新增代码部分*/

const backWithRouteName = createAction(BACK_WITH_ROUTE_RNAME);


第32行

Back: BACK,

/*新增代码部分*/

BackWithRouteName: BACK_WITH_ROUTE_RNAME,


第68行

BACK,

/*新增代码部分*/

BACK_WITH_ROUTE_RNAME,


第78行

back,

/*新增代码部分*/

backWithRouteName,


3.typeDefinition.js文件

第184行

export type NavigationBackAction = {

type: 'Navigation/BACK',

key?: ?string,

};

  /*新增代码部分*/

export type NavigationBackWithRouteNameAction = {

type: 'Navigation/BACK_WITH_ROUTE_RNAME',

routeName: string,

key?: ?string,

};

4.StackRouter.js文件

if (action.type === NavigationActions.BACK) {

let backRouteIndex = null;

if (action.key) {

const backRoute = state.routes.find(

/* $FlowFixMe */

(route: *) => route.key === action.key

);

/* $FlowFixMe */

backRouteIndex = state.routes.indexOf(backRoute);

}

if (backRouteIndex == null) {

return StateUtils.pop(state);

}

if (backRouteIndex > 0) {

return {

...state,

routes: state.routes.slice(0, backRouteIndex),

index: backRouteIndex - 1,

};

}

}

/*新增代码部分*/

if (action.type === NavigationActions.BACK_WITH_ROUTER_RNAME) {

let backRouteIndex = null;

if (action.routeName) {

const backRoute = state.routes.find(

/* $FlowFixMe */

(route: *) => route.routeName === action.routeName

);

/* $FlowFixMe */

backRouteIndex = state.routes.indexOf(backRoute);

}

if (backRouteIndex == null) {

return StateUtils.pop(state);

}

if (backRouteIndex >= 0) {

return {

...state,

routes: state.routes.slice(0, backRouteIndex + 1),

index: backRouteIndex - 1 + 1,

};

}

}

以上四个文件内容修改完毕后保存即可.goBackWithRouteName(routeName)使用方法类似goBack().

对比兔神的实现方法,这个方法同样实现了根据routeName回跳到指定页面的功能,但是修改步骤较复杂,优点是大家可以参照此方法实现过程,自定义自己需要的其他方法.提高大家对于react-navigation的扩展能力.

日记本