最近需求维护老的 RN 项目,需求晋级到最新的版本。晋级下来,首要涉及第三方库适配 androidx 及 react-navigaiton6 的晋级。androidx 的晋级首要是一些库的晋级,包含不维护的库 fork 或许建议 pr,相对比较惯例。首要的工作量在 react-navigation 这一次层。(参照 5.x 的晋级文档)
一般改动点
navigation 4.x 之前经过 route configuration 装备,5.x 以上经过组件的嵌套,和 react-router 比较类似。可参照文档,修正tab,nav嵌套关系
// 4.x
const RootStack = createStackNavigator({
Home: { screen: HScreen, navigationOptions: { title: 'My app' },
})
// 5.x
const RootStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name='Home' component={HScreen} options={{ title: 'My app' }} />
</Stack.Navigator>
);
}
首要改动点
-
传值(params)
5.x 获取params,之前经过navigation拿到state,现在需求从route取,this.props.route 或许经过 useRoute 拿到route目标。
-
事情订阅(events)
订阅的事情只要(focus,blur),之前的willxx,didxx需求修正,remove的办法为了兼容hooks,改成函数回来的办法,既this.unsubsubscribe()
-
跳转(dispatch action)
action 改动比较大,之前的NavigationActions被移除,改成了CommonAction,之前比较臃肿的写法也变得简洁了些。
// 4.x const navigateAction = NavigationActions.navigate({ routeName: 'Profile', params: {}, action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }), }); // 5.x reset const navigateAction = actionToCustom(1, [{ name: 'Profile' }, { name: 'SubProfileRoute' }]); // 多级跳转使用 state 装备 const navigateAction = CommonActions.reset({ index: 0, params: { version: '6.x' }, routes: [{ name: 'Profile', state: { routes: [{ name: 'SubProfileRoute' }], index: 0 } }], }); // 5.x goback const backAction = { ...CommonActions.goBack(), // key从route中获取 source: key, }; // dispatch navigation.dispatch(action);
-
withNavigation(子组件传递navigation)
4.x版簿本组件能够使用withNavigation包装,使用onRef获取组件目标引用。新版本移除withNavigation,需求手动处理onRef,可改成ref或许在子组件中处理下onRef
// 经过 function component 包装传入 navigaiton,route const UserBannerWrap = (props)=>{ const navigation = useNavigation(); const route = useRoute(); const bannerRef = useRef(); useEffect(()=>{ props.onRef && props.onRef(bannerRef.current) }) return ( // 可兼容 class component <View {...props} navigation={navigation} route={route} ref={bannerRef} /> ); } // withNavigation 可从 @react-navigation/compat 包中获取,兼容老的Api,但是获取route中的params,还需求手动处理,感觉没有太必要 const UserBannerWrap = withNavigation(ClassView)
-
自定义路由(阻拦action)
5.x版本无法经过顶层的navigator component获取getStateForAction及action changge的办法。如需求阻拦action type,比方
BACK
,RESET
等,需求修正createStackNavigator
,createBottomTabNavigator
的完成办法。比方要阻拦navStack,可检查createStackNavigator的完成代码,一般在同名的xx.d.ts的根目录的src下,也可直接检查package.json的types机source的路径。然后复制下,可参照文档。
一般只需求从实例化Router(可为StackRouter,tabRouter只是类型不同), 然后即可阻拦getStateForAction,getStateForRouteNamesChange等办法,结合业务处理跳转。在经过useNavigationBuilder办法中传入自定义的Router,导出即可。