目录结构设计、组件设计模式、代码组织、项目架构最佳实践
本课程将详细介绍React项目架构的相关知识和实践技巧,包括目录结构设计、组件设计模式、代码组织方式、状态管理架构等核心概念。
// 展示组件 (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;
// 高阶组件示例
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 (
);
}
// 渲染属性模式
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}
)}
);
}
// 自定义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}
))}
);
}
// 模块化示例
// 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);
}
}
// 路由配置
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(
);
// 代码分割
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;
// 组件优化
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;
// 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
}
设计并实现一个简单的React项目目录结构,包含以下内容:
实现一个包含以下功能的React组件:
构建一个完整的React应用架构,包含以下功能:
重构一个现有React项目,应用所学的架构知识:
通过本课程学习,你应该掌握了React项目架构的核心知识和实践技巧:
一个良好的项目架构可以提高代码的可维护性、可扩展性和性能。继续深入学习和实践,你将能够构建更加专业和高效的React应用。