React Native (RN)动态权限路由导航(react-navigation)配置

React Native 动态权限路由导航(react-navigation)配置

1,实现背景
项目中可能会遇到权限路由配置的需求,根据不同账户权限,去动态的进行导航路由的显隐,以及不同的机型适配,那么我们就需要进行基于后端权限动态的生成相关路由配置。

2,实现思路
其实实现动态路由就是把不同类型的(StackNavigator,TabNavigator,DrawerNavigator)导航,动态的配置它们的RoutConfigs,NavigatorConfig属性。前者配置组件路由,后者配置导航样式属性等。

用过react-navigation的小伙伴应该知道一般的RoutConfigs都是写死的静态配置。但这种静态配置无法像更改navigatorConfig那样通过页面静态配置,动态配置去改变,那么我们就只能在创建相关类型的路由实例之前去动态的更改RoutConfigs以进行动态权限配置。

3,实现细节
登录成功–访问权限接口–基于权限配置RouConfigs
*注意: 使用hooks useEffect监听AppNavigatorRefresh属性,每次新用户登录时进行触发,然后重新创建AppContainer,进行路由导航重新渲染。global:为node全局属性declare var global: typeof globalThis;

登录

    actions.userLogin(body, {
      resolved: (res) => {
		 // something
        // 登录成功后进行权限初始化
        global.tabNavigatoeRefresh().then(() => {
          // 初始化完成后再进行登录成功页面初始化跳转
          const resetActions = StackActions.reset({
            index: 0,
            actions: [NavigationActions.navigate({ routeName: 'Main' })],
          });
          this.props.navigation.dispatch(resetActions);
        });
      },
      rejected: (msg) => {
        this.props.actions.loading(false);
        actions.toast(msg);
      },
    });

访问权限接口

    // 用户切换时权限菜单初始化回调函数
    global.tabNavigatoeRefresh = () => {
      return new Promise((resolve, reject) => {
        const { AppNavigatorRefresh } = this.state;
        userService.getPermission({ lan: i18n.locale }).then(
          (res) => {
            this.setState({
              AppNavigatorRefresh: !AppNavigatorRefresh,
              PermissionArray: res?.data,
            });
            resolve();
          },
          () => {
            // 接口调用异常时不基于权限初始化,使用静态默认Roufings
            this.setState({
              AppNavigatorRefresh: !AppNavigatorRefresh,
              PermissionArray: null,
            });
            resolve();
          }
        );
      });
    };
    render() {
    const { refresh, drawerView, unReadMsgCount, AppNavigatorRefresh, PermissionArray } = this.state;
	return (
	<AppForNavigator
            refresh={refresh}
            PermissionArray={PermissionArray}
            unReadMsgCount={unReadMsgCount}
            AppNavigatorRefresh={AppNavigatorRefresh}
          />
)
}

基于权限配置RouConfigs

const AppForNavigator = (props) => {
  const { PermissionArray, AppNavigatorRefresh } = props;
  useEffect(() => {
    if (PermissionArray) {
      // 基于账户权限进行权限动态配置,重新创建新的AppContainer
      // 将MainHome路由导航配置抽离成动态可配置变量
      if (!PermissionArray?.some((e) => e?.permission === 'overview.view')) {
        navigatorConfigs.Main = MainHome({ isDelete: true });
      } else {
        navigatorConfigs.Main = MainHome({ isDelete: false });
      }
      AppContainer = createAppContainer(
        createStackNavigator(navigatorConfigs, {
          defaultNavigationOptions: ({ navigation }) =>
            StackOptions({
              navigation,
            }),
        })
      );
      // 创建之后进行AppContainer刷新
      global.refresh();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [AppNavigatorRefresh]);
  return (
    <AppContainer
      ref={(navigatorRef) => {
        NavigationService.setTopLevelNavigator(navigatorRef);
      }}
      screenProps={{
        refresh: props.refresh,
        unReadMsgCount: props.unReadMsgCount === 0 ? null : props.unReadMsgCount,
      }}
    />
  );
};
export default AppForNavigator;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值