<返回目录     Powered by claud/xia兄

第13课: 项目架构

目录结构设计、组件设计模式、代码组织、项目架构最佳实践

课程内容

本课程将详细介绍React项目架构的相关知识和实践技巧,包括目录结构设计、组件设计模式、代码组织方式、状态管理架构等核心概念。

核心概念

1. 项目架构基础

2. 目录结构设计

2.1 基础目录结构

├── public/ # 静态资源 │ ├── index.html # HTML模板 │ ├── favicon.ico # 网站图标 │ └── manifest.json # PWA配置 ├── src/ # 源代码 │ ├── components/ # 可复用组件 │ │ ├── common/ # 通用组件 │ │ └── layout/ # 布局组件 │ ├── pages/ # 页面组件 │ │ ├── Home/ # 首页 │ │ ├── About/ # 关于页 │ │ └── Dashboard/ # 仪表盘 │ ├── hooks/ # 自定义Hooks │ ├── context/ # 上下文管理 │ ├── services/ # API服务 │ ├── utils/ # 工具函数 │ ├── styles/ # 全局样式 │ ├── assets/ # 静态资源 │ ├── routes/ # 路由配置 │ ├── store/ # 状态管理 │ │ ├── slices/ # Redux slices │ │ └── index.js # Store配置 │ ├── App.jsx # 应用根组件 │ └── main.jsx # 应用入口 ├── package.json # 项目配置 ├── vite.config.js # Vite配置 ├── .eslintrc.cjs # ESLint配置 ├── .prettierrc # Prettier配置 └── README.md # 项目说明

2.2 目录结构最佳实践

3. 组件设计模式

3.1 容器组件与展示组件

// 展示组件 (Presentational Component)
import React from 'react';

function UserCard({ user, onEdit, onDelete }) {
  return (
    

{user.name}

{user.email}

); } export default UserCard; // 容器组件 (Container Component) import React, { useState, useEffect } from 'react'; import UserCard from './UserCard'; import { fetchUser } from '../services/api'; function UserContainer({ userId }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const loadUser = async () => { try { setLoading(true); const data = await fetchUser(userId); setUser(data); } catch (err) { setError('加载用户失败'); } finally { setLoading(false); } }; loadUser(); }, [userId]); const handleEdit = () => { // 编辑用户逻辑 console.log('编辑用户:', user.id); }; const handleDelete = () => { // 删除用户逻辑 console.log('删除用户:', user.id); }; if (loading) return
加载中...
; if (error) return
{error}
; if (!user) return
用户不存在
; return ( ); } export default UserContainer;

3.2 高阶组件 (HOC)

// 高阶组件示例
import React from 'react';

// 带加载状态的HOC
function withLoading(Component) {
  return function WithLoadingComponent({ isLoading, ...props }) {
    if (isLoading) {
      return 
加载中...
; } return ; }; } // 带错误处理的HOC function withErrorHandling(Component) { return function WithErrorHandlingComponent({ error, ...props }) { if (error) { return
{error}
; } return ; }; } // 使用HOC import UserList from './UserList'; const UserListWithLoading = withLoading(UserList); const UserListWithError = withErrorHandling(UserListWithLoading); function App() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); // 数据加载逻辑... return ( ); }

3.3 渲染属性 (Render Props)

// 渲染属性模式
import React, { useState } from 'react';

function Counter({ render }) {
  const [count, setCount] = useState(0);
  
  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);
  
  return render({ count, increment, decrement });
}

// 使用渲染属性
function CounterDisplay() {
  return (
     (
        

计数器: {count}

)} /> ); } // 或者使用children作为render prop function CounterWithChildren({ children }) { const [count, setCount] = useState(0); const increment = () => setCount(count + 1); const decrement = () => setCount(count - 1); return children({ count, increment, decrement }); } function CounterDisplay2() { return ( {({ count, increment, decrement }) => (

计数器: {count}

)}
); }

3.4 自定义Hook模式

// 自定义Hook模式
import { useState, useEffect, useCallback } from 'react';

// 数据获取Hook
function useFetch(url, options = {}) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  
  const fetchData = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const response = await fetch(url, options);
      if (!response.ok) {
        throw new Error('请求失败');
      }
      const result = await response.json();
      setData(result);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [url, options]);
  
  useEffect(() => {
    fetchData();
  }, [fetchData]);
  
  return { data, loading, error, refetch: fetchData };
}

// 本地存储Hook
function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error('Error reading localStorage:', error);
      return initialValue;
    }
  });
  
  const setStoredValue = useCallback((newValue) => {
    try {
      setValue(newValue);
      window.localStorage.setItem(key, JSON.stringify(newValue));
    } catch (error) {
      console.error('Error setting localStorage:', error);
    }
  }, [key]);
  
  return [value, setStoredValue];
}

// 使用自定义Hook
function UserList() {
  const { data: users, loading, error, refetch } = useFetch('https://api.example.com/users');
  
  if (loading) return 
加载中...
; if (error) return
{error}
; return (

用户列表

    {users?.map(user => (
  • {user.name}
  • ))}
); }

4. 代码组织最佳实践

4.1 组件组织

4.2 代码风格

4.3 模块化

// 模块化示例
// services/api.js
const API_BASE_URL = 'https://api.example.com';

class ApiService {
  constructor() {
    this.baseURL = API_BASE_URL;
  }
  
  async request(endpoint, options = {}) {
    try {
      const response = await fetch(`${this.baseURL}${endpoint}`, {
        ...options,
        headers: {
          'Content-Type': 'application/json',
          ...options.headers
        }
      });
      
      if (!response.ok) {
        throw new Error('请求失败');
      }
      
      return await response.json();
    } catch (error) {
      console.error('API请求错误:', error);
      throw error;
    }
  }
  
  // 用户相关API
  async getUsers() {
    return this.request('/users');
  }
  
  async getUser(id) {
    return this.request(`/users/${id}`);
  }
  
  async createUser(userData) {
    return this.request('/users', {
      method: 'POST',
      body: JSON.stringify(userData)
    });
  }
}

export default new ApiService();

// 使用API服务
import api from '../services/api';

async function loadUsers() {
  try {
    const users = await api.getUsers();
    console.log('用户列表:', users);
  } catch (error) {
    console.error('加载用户失败:', error);
  }
}

5. 状态管理架构

5.1 状态分层

5.2 状态管理最佳实践

6. 路由架构

6.1 路由配置

// 路由配置
import { createBrowserRouter } from 'react-router-dom';
import App from '../App';
import Home from '../pages/Home';
import About from '../pages/About';
import Dashboard from '../pages/Dashboard';
import NotFound from '../pages/NotFound';
import ProtectedRoute from '../components/ProtectedRoute';

const router = createBrowserRouter([
  {
    path: '/',
    element: ,
    errorElement: ,
    children: [
      {
        index: true,
        element: 
      },
      {
        path: 'about',
        element: 
      },
      {
        path: 'dashboard',
        element: ,
        children: [
          {
            index: true,
            element: 
          }
        ]
      }
    ]
  }
]);

export default router;

// 应用入口
import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider } from 'react-router-dom';
import router from './routes';

ReactDOM.createRoot(document.getElementById('root')).render(
  
    
  
);

7. 性能优化架构

7.1 代码分割

// 代码分割
import { lazy, Suspense } from 'react';
import { createBrowserRouter } from 'react-router-dom';

// 懒加载组件
const Home = lazy(() => import('../pages/Home'));
const About = lazy(() => import('../pages/About'));
const Dashboard = lazy(() => import('../pages/Dashboard'));
const NotFound = lazy(() => import('../pages/NotFound'));

// 加载中组件
const Loading = () => 
加载中...
; const router = createBrowserRouter([ { path: '/', element: ( }> ), children: [ { index: true, element: ( }> ) }, { path: 'about', element: ( }> ) }, { path: 'dashboard', element: ( }> ) } ] } ]); export default router;

7.2 组件优化

// 组件优化
import React, { memo, useMemo, useCallback } from 'react';

// 使用memo优化组件渲染
const ExpensiveComponent = memo(({ data, onUpdate }) => {
  console.log('ExpensiveComponent渲染');
  
  // 计算密集型操作
  const processedData = useMemo(() => {
    return data.map(item => ({ ...item, value: item.value * 2 }));
  }, [data]);
  
  // 避免在render中创建新函数
  const handleUpdate = useCallback((id) => {
    onUpdate(id);
  }, [onUpdate]);
  
  return (
    
{processedData.map(item => (
{item.name}: {item.value}
))}
); }); export default ExpensiveComponent;

8. 项目配置与工具

8.1 开发工具

8.2 配置文件

// package.json示例
{
  "name": "react-app",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "format": "prettier --write ."
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.22.0",
    "@reduxjs/toolkit": "^2.0.0",
    "react-redux": "^9.0.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.43",
    "@types/react-dom": "^18.2.17",
    "@vitejs/plugin-react": "^4.2.1",
    "eslint": "^8.55.0",
    "eslint-plugin-react": "^7.33.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.5",
    "prettier": "^3.1.1",
    "vite": "^5.0.8"
  }
}

// .eslintrc.cjs示例
module.exports = {
  root: true,
  env: { browser: true, es2020: true },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:react/jsx-runtime'
  ],
  ignorePatterns: ['dist', '.eslintrc.cjs'],
  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
  settings: { react: { version: '18.2' } },
  plugins: ['react-refresh'],
  rules: {
    'react/jsx-no-target-blank': 'off',
    'react-refresh/only-export-components': [
      'warn',
      { allowConstantExport: true }
    ]
  }
};

// .prettierrc示例
{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 80,
  "tabWidth": 2
}
最佳实践:
注意事项:

实践练习

练习任务:
  1. 基础练习:

    设计并实现一个简单的React项目目录结构,包含以下内容:

    • 组件目录结构
    • 页面组件
    • 服务层
    • 工具函数
  2. 中级练习:

    实现一个包含以下功能的React组件:

    • 使用容器组件和展示组件模式
    • 使用自定义Hook管理逻辑
    • 实现组件的性能优化
  3. 高级练习:

    构建一个完整的React应用架构,包含以下功能:

    • 路由配置
    • 状态管理
    • API服务
    • 代码分割
    • 性能优化
  4. 综合练习:

    重构一个现有React项目,应用所学的架构知识:

    • 优化目录结构
    • 改进组件设计
    • 优化状态管理
    • 提升代码质量

总结

通过本课程学习,你应该掌握了React项目架构的核心知识和实践技巧:

一个良好的项目架构可以提高代码的可维护性、可扩展性和性能。继续深入学习和实践,你将能够构建更加专业和高效的React应用。