GitHub_Trending/rea/react-conf-app:React 项目中的整洁架构实现

【免费下载链接】react-conf-app 【免费下载链接】react-conf-app 项目地址: https://gitcode.com/GitHub_Trending/rea/react-conf-app

你是否在开发 React 应用时遇到过状态管理混乱、组件复用困难、业务逻辑与 UI 代码交织的问题?本文将通过分析开源项目 GitHub_Trending/rea/react-conf-app 的代码结构,展示如何在 React 项目中实现整洁架构,解决这些常见痛点。读完本文,你将了解如何通过类型定义、状态管理、工具函数和组件设计四个层面构建清晰、可维护的 React 应用。

类型定义:构建数据模型基础

整洁架构的核心是依赖规则——内层不依赖外层,而类型定义正是架构的最内层,为整个应用提供稳定的数据模型。在 react-conf-app 中,src/types.ts 文件定义了应用的核心数据结构:

export type Session = {
  id: string;
  title: string;
  description: string | null;
  startsAt: string;
  endsAt: string;
  speakers: Speaker[];
  room: string;
  isServiceSession: boolean;
};

export type Speaker = {
  id: string;
  firstName: string;
  lastName: string;
  bio: string | null;
  tagLine: string | null;
  profilePicture: string | null;
  links: { title: string; url: string; linkType: string }[];
  sessions: number[];
  fullName: string;
  categoryItems: number[];
};

这些类型定义不仅约束了数据结构,还通过 TypeScript 的类型检查确保了数据在应用各层之间的一致性传递。例如 Session 类型明确规定了会议信息的组成,包括标题、时间、演讲者等必要字段,为后续状态管理和 UI 渲染提供了可靠的数据契约。

状态管理:隔离业务逻辑与 UI

在整洁架构中,业务逻辑应该独立于 UI 框架。react-conf-app 使用 Zustand 状态管理库实现了这一目标,将业务逻辑封装在 store 中,与 UI 组件解耦。src/store/reactConfStore.ts 文件展示了如何设计一个可维护的状态管理模块:

type ConfState = {
  schedule: {
    dayOne: Session[];
    dayTwo: Session[];
  };
  allSessions: ApiAllSessions;
  isRefreshing?: boolean;
  lastRefreshed: string | null;
  refreshData: (options?: { ttlMs?: number }) => Promise<void>;
  shouldUseLocalTz: boolean;
  toggleLocalTz: () => void;
};

export const useReactConfStore = create(
  persist<ConfState>(
    (set, get) => ({
      ...getInitialSchedule(),
      isRefreshing: false,
      lastRefreshed: null,
      shouldUseLocalTz: false,
      refreshData: async (options) => {
        // 数据刷新逻辑
      },
      toggleLocalTz: () => {
        set((state) => ({ shouldUseLocalTz: !state.shouldUseLocalTz }));
      },
    }),
    {
      name: "react-conf-2025-store",
      storage: createJSONStorage(() => AsyncStorage),
    }
  )
);

该 store 实现了几个关键特性:

  1. 使用 persist 中间件实现状态持久化,确保应用重启后数据不丢失
  2. 通过 refreshData 方法封装数据获取和更新逻辑,隔离网络请求细节
  3. 提供 shouldUseLocalTz 状态和 toggleLocalTz 方法,实现时区切换功能

这种设计使业务逻辑与 UI 组件分离,组件只需通过 useReactConfStore hook 获取所需状态和方法,无需关心数据来源和更新方式。

工具函数:处理数据转换与业务规则

整洁架构中的用例层负责实现业务规则,在 react-conf-app 中,这一职责由工具函数承担。src/utils/sessions.ts 文件中的函数处理会议数据的格式化和转换:

export const formatSessions = (talks: ApiAllSessions): Session[][] => {
  const allSessions = talks.sessions.map((talk) => ({
    id: talk.id,
    title: talk.title,
    description: talk.description,
    startsAt: talk.startsAt,
    endsAt: talk.endsAt,
    speakers: (talk.speakers
      ?.map((speakerId) => talks.speakers.find((sp) => sp.id === speakerId))
      .filter(Boolean) || []) as Speaker[],
    room: talks.rooms.find((room) => room.id === talk.roomId)?.name || "...",
  }));

  const dayOne = allSessions.filter((session) =>
    isDayOneSession(session.startsAt),
  );

  const dayTwo = allSessions.filter((session) =>
    isDayTwoSession(session.startsAt),
  );

  return [dayOne, dayTwo];
};

formatSessions 函数接收原始 API 数据,将其转换为 UI 组件可直接使用的格式,并根据日期将会议分为两天。这种数据转换逻辑独立于 UI 组件,便于测试和复用。类似地,src/utils/formatDate.ts 文件中的函数处理日期格式化和时区转换,确保整个应用使用一致的日期处理规则。

组件设计:构建可复用的 UI 模块

在整洁架构的最外层是接口适配层,对应 react-conf-app 中的 UI 组件。项目采用组件化设计,将 UI 拆分为多个职责单一的组件,例如 src/components/TalkCard.tsxsrc/components/SpeakerDetails.tsx

React Conf App 界面

组件设计遵循以下原则:

  1. 单一职责:每个组件只负责一个功能,如 TalkCard 专注于展示会议信息
  2. 数据驱动:通过 props 接收数据,不直接操作状态
  3. 平台适配:针对不同平台提供特定实现,如 Bookmark.ios.tsxBookmark.tsx

例如,src/components/MiniTalkCard.tsx 组件展示精简的会议信息,通过 props 接收会议数据并渲染:

type MiniTalkCardProps = {
  session: Session;
  isFirst?: boolean;
  isLast?: boolean;
  onPress?: () => void;
};

export function MiniTalkCard({ session, isFirst, isLast, onPress }: MiniTalkCardProps) {
  return (
    <PressableArea
      onPress={onPress}
      style={[
        styles.container,
        isFirst && styles.first,
        isLast && styles.last,
      ]}
    >
      <View style={styles.timeContainer}>
        <Text style={styles.timeText}>
          {formatTime(session.startsAt, shouldUseLocalTz)}
        </Text>
      </View>
      <View style={styles.content}>
        <Text style={styles.title}>{session.title}</Text>
        <Text style={styles.speakerNames}>
          {session.speakers.map(s => s.fullName).join(", ")}
        </Text>
      </View>
      <Bookmark sessionId={session.id} />
    </PressableArea>
  );
}

项目结构:遵循整洁架构的目录组织

react-conf-app 的目录结构清晰反映了整洁架构的层次划分:

src/
├── app/              # 路由和页面组件(最外层)
├── components/       # UI组件(接口适配层)
├── consts.ts         # 常量定义
├── data/             # 原始数据
├── hooks/            # 自定义Hooks
├── store/            # 状态管理(领域层)
├── theme.ts          # 主题配置
├── types.ts          # 类型定义(实体层)
└── utils/            # 工具函数(用例层)

这种结构确保了依赖规则的遵循:内层(types, utils, store)不依赖外层(components, app),所有依赖都指向内部。例如,工具函数只依赖类型定义,不依赖 UI 组件;状态管理依赖工具函数和类型定义,但不依赖具体组件。

总结与实践建议

通过分析 react-conf-app,我们可以总结出在 React 项目中实现整洁架构的几个关键实践:

  1. 定义清晰的类型模型:使用 TypeScript 定义核心业务实体,如 src/types.ts 中的 SessionSpeaker 类型
  2. 隔离业务逻辑:将状态管理和业务规则封装在 store 和工具函数中,如 src/store/reactConfStore.tssrc/utils/sessions.ts
  3. 组件化 UI:构建职责单一、可复用的组件,如 src/components/ 目录下的各类组件
  4. 合理组织目录:按整洁架构的层次划分目录,确保依赖方向正确

这些实践有助于构建可维护、可测试、易于扩展的 React 应用,特别适合中大型项目和长期维护的产品。如果你想进一步了解项目细节,可以查看项目的 README.md 或直接浏览源代码。

【免费下载链接】react-conf-app 【免费下载链接】react-conf-app 项目地址: https://gitcode.com/GitHub_Trending/rea/react-conf-app

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐