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的扩展能力.