10-8 根据选中类别动态生成首页模块的顶部标签导航器和modal

在之前的章节中,我们已经完成了分类模块的功能。在这一节中,我们将根据用户选择的类别动态生成首页的顶部标签导航器和 Model。

一、动态生成顶部标签导航器

  1. 更新 HomeTabs.tsx 文件

    navigator/HomeTab.tsx 文件中,使用 createMaterialTopTabNavigator 创建导航器,并根据用户选择的类别动态生成标签页:

    typescript 复制代码
    import React from 'react';
    import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
    import { connect, ConnectedProps } from 'react-redux';
    import { RootState } from '@/models/index';
    import Home from '@/pages/Home';
    
    export type HomeTabParamList = {
      [key: string]: {
        modelNamespace: string;
        category: string;
      };
    };
    
    const Tab = createMaterialTopTabNavigator<HomeTabParamList>();
    
    const mapStateToProps = ({ category }: RootState) => ({
      myCategorys: category.myCategorys,
    });
    
    const connector = connect(mapStateToProps);
    
    type IProps = ConnectedProps<typeof connector>;
    
    function HomeTabs({ myCategorys }: IProps) {
      return (
        <Tab.Navigator>
          {myCategorys.map((category) => (
            <Tab.Screen
              key={category.id}
              name={category.id}
              component={Home}
              options={{
                tabBarLabel: category.name,
              }}
              initialParams={{
                modelNamespace: category.id,
                category: category.id,
              }}
            />
          ))}
        </Tab.Navigator>
      );
    }
    
    export default connector(HomeTabs);

二、动态生成 Model

  1. 安装 dva-model-extend

    bash 复制代码
    yarn add dva-model-extend
  2. 创建 createModel 函数

    models 文件夹中创建一个 createModel.ts 文件:

    typescript 复制代码
    import modelExtend from 'dva-model-extend';
    import home from '@/models/home';
    
    interface Cached {
      [key: string]: number;
    }
    
    const cached: Cached = {
      home: 1,
    };
    
    function registerModel(model: Model) {
      if (!cached[model.namespace]) {
        app.model(model);
        cached[model.namespace] = 1;
      }
    }
    
    export function createModel(namespace: string) {
      const model = modelExtend(home, {
        namespace,
      });
    
      registerModel(model);
    }
  3. 更新 HomeTabs.tsx 文件

    HomeTabs.tsx 文件中,动态生成 Model 并绑定到导航器:

    typescript 复制代码
    import { createModel } from '@/models/createModel';
    
    function HomeTabs({ myCategorys }: IProps) {
      myCategorys.forEach((category) => {
        createModel(category.id);
      });
    
      return (
        <Tab.Navigator>
          {myCategorys.map((category) => (
            <Tab.Screen
              key={category.id}
              name={category.id}
              component={Home}
              options={{
                tabBarLabel: category.name,
              }}
              initialParams={{
                modelNamespace: category.id,
                category: category.id,
              }}
            />
          ))}
        </Tab.Navigator>
      );
    }

三、更新页面组件

  1. 更新 Home 页面的 mapStateToProps

    typescript 复制代码
    import { findRouteNameFromNavigatorState } from '@/utils/index';
    
    const mapStateToProps = (
      state: RootState,
      props: { route: { params: { modelNamespace: string } } }
    ) => {
      const { modelNamespace } = props.route.params;
      const modelState = state[modelNamespace];
      return {
        carousels: modelState.carousels,
        channels: modelState.channels,
        hasMore: modelState.pagination.hasMore,
        gradientVisible: modelState.gradientVisible,
        loading: state.loading.effects['home/fetchChannels'],
      };
    };
  2. 创建 findRouteNameFromNavigatorState 函数

    utils/index.ts 文件中创建该函数:

    typescript 复制代码
    export function findRouteNameFromNavigatorState(
      state: NavigationState
    ): string {
      let route = state.routes[state.index];
      while (route.state) {
        route = route.state.routes[route.state.index];
      }
      return route.name;
    }

四、总结

在本节中,我们根据用户选择的类别动态生成了首页的顶部标签导航器和 Model。通过使用 dva-model-extend 库,我们能够动态创建 Model,确保每个标签页的数据独立。这样,每个标签页都可以根据选择的类别独立加载和显示数据。

下一节,我们将学习如何实现手势响应系统,完成频道模块的功能。

相关推荐
恋猫de小郭1 分钟前
AI 时代,一个优化 Flutter 的重复代码工具 Deslop
android·前端·flutter
穗余1 分钟前
Typescript let和var区别
前端·javascript·typescript
晓得迷路了6 分钟前
栗子前端技术周刊第 144 期 - Rspack 2.2、pnpm 12、Solid 2.0 RC...
前端·javascript·css
YHHLAI12 分钟前
前端路由与浏览器历史:从多页应用到单页应用的演进
前端
Escalating_xu19 分钟前
【C++类和对象(上)】从类的定义、封装与对象模型到内存对齐和 this 指针
开发语言·前端·c++
Json____22 分钟前
宿舍安全卫生检查系统:Node 全栈开发实战
java·前端·数据库·毕业设计·课程设计·毕设·wwwoop.com
晴天1627 分钟前
HTML canvas标签使用指南-Day32
前端·html
weixin1997010801630 分钟前
《alibaba.idle.isv.order.ship 接入实录:闲鱼订单发货回传的5个隐式约束》(附Python源码)
服务器·前端·python
初願致夕霞37 分钟前
五种IO模型(详解非阻塞IO与多路转接)
linux·前端·网络·数据库·tcp/ip