在之前的章节中,我们已经完成了分类模块的功能。在这一节中,我们将根据用户选择的类别动态生成首页的顶部标签导航器和 Model。
一、动态生成顶部标签导航器
-
更新
HomeTabs.tsx
文件在
navigator/HomeTab.tsx
文件中,使用createMaterialTopTabNavigator
创建导航器,并根据用户选择的类别动态生成标签页:typescriptimport 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
-
安装
dva-model-extend
bashyarn add dva-model-extend
-
创建
createModel
函数在
models
文件夹中创建一个createModel.ts
文件:typescriptimport 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); }
-
更新
HomeTabs.tsx
文件在
HomeTabs.tsx
文件中,动态生成 Model 并绑定到导航器:typescriptimport { 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> ); }
三、更新页面组件
-
更新
Home
页面的mapStateToProps
typescriptimport { 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'], }; };
-
创建
findRouteNameFromNavigatorState
函数在
utils/index.ts
文件中创建该函数:typescriptexport 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,确保每个标签页的数据独立。这样,每个标签页都可以根据选择的类别独立加载和显示数据。
下一节,我们将学习如何实现手势响应系统,完成频道模块的功能。