Skip to content

UMI app.tsx 作用及其使用场景

在 UMI(UmiJS)项目中,app.tsx 不是默认必须存在的文件,但在某些情况下,它可以提供全局级别的功能,如状态管理、错误边界和应用初始化。本篇文档将介绍 app.tsx 的作用,并划分出哪些情况下必须使用它,哪些情况下可以不使用它。

什么是 app.tsx

app.tsx 是 UMI 提供的一个全局扩展文件,它的主要作用是对应用进行全局增强,例如:

  • 全局 Context 管理(如 React Context、Redux Provider)

  • 错误边界(ErrorBoundary)

  • 应用启动时执行初始化逻辑

  • 自定义根容器 rootContainer

app.tsx 默认不会自动生成,但如果你在 src/ 目录下创建它,UMI 会自动识别并使用。

什么时候必须使用 app.tsx

如果你的项目需要以下功能,那么 app.tsx 就是必须的:

全局状态管理(Context 或 Redux)

如果你的项目使用 React Context 或 Redux 进行全局状态管理,app.tsx 是必要的,因为它可以将 Provider 包裹整个应用。

示例:使用 React Context 进行全局状态管理

tsx
// src/app.tsx
import React from "react";
import { ThemeProvider } from "./context/ThemeContext"; // 你的自定义 Context

export function rootContainer(container: React.ReactNode) {
  return <ThemeProvider>{container}</ThemeProvider>;
}

全局错误边界(ErrorBoundary)

如果你希望在应用发生错误时,能够捕获错误并显示友好的错误页面,而不是白屏,那么你需要 app.tsx 作为全局错误边界。

  • 示例:添加全局错误边界
tsx
// src/components/ErrorBoundary.tsx
import React from "react";

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error: any, errorInfo: any) {
    console.error("Caught an error:", error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

export default ErrorBoundary;
  • 然后在app.tsx中使用它
tsx
// src/app.tsx
import React from "react";
import ErrorBoundary from "./components/ErrorBoundary";

export function rootContainer(container: React.ReactNode) {
  return <ErrorBoundary>{container}</ErrorBoundary>;
}

在应用启动时执行初始化逻辑

如果你希望在应用启动时执行一些全局操作(比如获取用户信息、加载全局配置等),你可以在 app.tsx 里使用 useEffect 或其他方法来处理。

tsx
// src/app.tsx
import React, { useEffect } from "react";

export function onAppCreated() {
  console.log("应用已启动");
  fetch("/api/init")
    .then((response) => response.json())
    .then((data) => console.log("初始化数据:", data));
}

修改rootContainer(如自定义布局)

如果你想在整个应用的根容器上添加额外的包装,比如 UI 主题提供器(Ant Design、Material UI)等,你需要 app.tsx

示例全局 UI 主题提供器

tsx
// src/app.tsx
import React from "react";
import { ConfigProvider } from "antd";

export function rootContainer(container: React.ReactNode) {
  return <ConfigProvider>{container}</ConfigProvider>;
}

什么时候可以不使用 app.tsx

如果你的项目仅依赖 routes.ts 进行路由管理,并且没有全局状态、错误边界或初始化逻辑,那么你可以不使用 app.tsx。

1. 仅依赖 routes.ts 进行页面导航

tsx
export default [
  { path: "/", redirect: "/login" },
  { path: "/login", component: "@/pages/Login" },
  { path: "/home", component: "@/pages/Home" },
];

那么 app.tsx 不是必须的,UMI 会直接基于 routes.ts 渲染页面。

2. 不需要全局状态管理

如果你的状态管理全部在组件内部处理,而不是用 ContextRedux,那么 app.tsx 也不是必须的。

3. 不需要全局错误处理

如果你没有特别的错误处理需求(比如只依赖 try-catch 或 console.error),那么 app.tsx 也可以省略。

4. app.tsx 是否影响 routes.ts

不会!app.tsx 主要用于全局增强,而 routes.ts 负责页面导航,两者互不影响。

如果你有 app.tsx,UMI 仍然会按照 routes.ts 的配置来渲染页面。