React 项目开发 的 进阶模式
以下是 React 开发 中 常见的 进阶概念 和 使用场景,这些知识 能够帮助你 在实际项目中 编写 更高效、更复杂 的 应用。
1 React Context
Context 是 React 提供的一种方式,用于在 组件树中 共享状态,而不需要 逐层通过 props
传递数据。
使用场景
- 主题切换
- 用户认证状态
- 全局设置
代码示例
import React, { createContext, useContext, useState } from 'react';
// 创建 Context
const ThemeContext = createContext();
// 提供 Context
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
// 使用 Context
function ThemeToggler() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Current theme: {theme}
</button>
);
}
function App() {
return (
<ThemeProvider>
<ThemeToggler />
</ThemeProvider>
);
}
2 React Portals
Portals 提供了一种将 子节点 渲染到 父组件 DOM 层次之外 的 DOM 节点 中 的 方法。
使用场景
- 模态框
- 工具提示(Tooltip)
- 弹出菜单
代码示例
import React from 'react';
import ReactDOM from 'react-dom';
function Modal({ children }) {
return ReactDOM.createPortal(
<div className="modal">
{children}
</div>,
document.getElementById('modal-root') // 假设这个节点存在于 HTML 中
);
}
function App() {
return (
<div>
<h1>My App</h1>
<Modal>
<p>This is a modal content.</p>
</Modal>
</div>
);
}
3 React Error Boundaries
Error Boundaries 用于捕获其 子组件树 中的 JavaScript 错误,并进行处理。它们 不会捕获 事件处理程序中的 错误。
使用场景
- 捕获 渲染错误,避免 整个应用崩溃
- 展示 错误提示 页面
代码示例
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error("Error caught:", error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
function BuggyComponent() {
throw new Error("Simulated Error");
}
function App() {
return (
<ErrorBoundary>
<BuggyComponent />
</ErrorBoundary>
);
}
4 Higher-Order Components (HOC)
HOC 是一个 函数,接收一个组件 并 返回一个新的组件,用于 逻辑复用。
使用场景
- 权限控制
- 数据加载
- 日志记录
代码示例
function withLogging(WrappedComponent) {
return function(props) {
console.log('Rendering component with props:', props);
return <WrappedComponent {...props} />;
};
}
function Hello({ name }) {
return <h1>Hello, {name}!</h1>;
}
const EnhancedHello = withLogging(Hello);
function App() {
return <EnhancedHello name="Alice" />;
}
5 Render Props
Render Props 是一种 模式,通过一个 返回 React 元素 的 函数 来 共享 组件之间的 逻辑。
使用场景
- 状态管理
- 动画控制
代码示例
function Mouse({ render }) {
const [position, setPosition] = React.useState({ x: 0, y: 0 });
const handleMouseMove = (event) => {
setPosition({ x: event.clientX, y: event.clientY });
};
return <div style={{ height: '100%' }} onMouseMove={handleMouseMove}>
{render(position)}
</div>;
}
function App() {
return (
<Mouse render={({ x, y }) => (
<h1>The mouse position is ({x}, {y})</h1>
)} />
);
}
6 React Refs
Refs 提供了一种方式,允许访问 DOM 节点 或 组件实例。
使用场景
- 管理焦点
- 操作非受控组件
- 动画
代码示例
import React, { useRef } from 'react';
function FocusInput() {
const inputRef = useRef(null);
const handleFocus = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleFocus}>Focus Input</button>
</div>
);
}
function App() {
return <FocusInput />;
}
7 React.memo 和 useMemo
- eact.memo:用于防止 不必要的 组件 重新渲染;
- useMemo:用于 缓存 计算结果,提高性能。
代码示例
import React, { useState, useMemo } from 'react';
const ExpensiveComponent = React.memo(({ count }) => {
console.log('Rendering ExpensiveComponent');
return <div>Count: {count}</div>;
});
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
return (
<div>
<ExpensiveComponent count={count} />
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<input value={text} onChange={(e) => setText(e.target.value)} />
</div>
);
}
8 Server-Side Rendering (SSR) 和 Static-Site Generation (SSG)
- SSR:在 服务器 上 渲染 React 组件,将 HTML 返回给 客户端;
- SSG:在构建时 生成静态 HTML 文件。
使用场景
- SEO 优化
- 首屏加载 性能优化
使用工具
Next.js(支持 SSR 和 SSG)。
9 Code Splitting 和 Lazy Loading
通过 动态加载 组件 来减少 初始加载 时间。
代码示例
import React, { Suspense, lazy } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}
10 状态管理库
- Redux:集中式 状态管理
- MobX:基于 响应式编程 的状态管理
- Recoil:专为 React 设计的 状态管理库