React 高级特性
本章将介绍 React 中的高级特性,包括 Portals、Error Boundary、Suspense 和 Strict Mode。
1. Portals(传送门)
Portals 允许将组件渲染到 DOM 树中的其他位置(例如 document.body),通常用于模态框、提示框等。
实时编辑器
function PortalExample() { const [show, setShow] = useState(false); return ( <div style={{ border: '1px solid #ccc', padding: '10px', position: 'relative', overflow: 'hidden' }}> <p>父容器设置了 overflow: hidden。</p> <button onClick={() => setShow(true)}>打开 Portal 模态框</button> {show && createPortal( <div style={{ position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', background: 'white', padding: '20px', boxShadow: '0 0 10px rgba(0,0,0,0.5)', zIndex: 9999 }}> <h3>这是一个 Portal</h3> <p>我被渲染到了 document.body 下,不受父容器限制!</p> <button onClick={() => setShow(false)}>关闭</button> </div>, document.body )} </div> ); }
结果
Loading...
2. Error Boundary(错误边界)
错误边界捕获子组件树中的渲染错误。注意:它必须是类组件。
实时编辑器
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError() { return { hasError: true }; } render() { if (this.state.hasError) return <div style={{ color: 'red' }}>组件渲染崩溃了!</div>; return this.props.children; } } function BuggyComponent() { const [crash, setCrash] = useState(false); if (crash) throw new Error("崩溃!"); return <button onClick={() => setCrash(true)}>触发渲染错误</button>; } function App() { return ( <ErrorBoundary> <BuggyComponent /> </ErrorBoundary> ); }
结果
Loading...
3. Suspense(悬念)
用于在等待异步内容(如代码分割组件或异步数据)时显示加载状态。
实时编辑器
const LazyComponent = React.lazy(() => new Promise(resolve => { setTimeout(() => resolve({ default: () => <p>我是懒加载加载出来的组件!</p> }), 2000); })); function App() { return ( <Suspense fallback={<p style={{ color: 'blue' }}>正在拼命加载中...</p>}> <LazyComponent /> </Suspense> ); }
结果
Loading...
4. Strict Mode(严格模式)
StrictMode 在开发环境下运行,主要用于发现潜在问题:
- 检测副作用。
- 警告过时的 API。
- 识别不安全的生命周期方法。
小结
- Portals:脱离父级布局限制。
- Error Boundaries:优雅处理渲染错误,防止整个应用白屏。
- Suspense:异步流程的 UI 等待方案。
- Strict Mode:开发期的"体检"工具。
Context 与性能优化
function AppProvider({ children }) {
const [state, setState] = useState(initialState);
// 使用 useMemo 防止不必要的重新渲染
const value = useMemo(() => ({
state,
dispatch: (action) => setState(reducer(state, action))
}), [state]);
return (
<AppContext.Provider value={value}>
{children}
</AppContext.Provider>
);
}
高级渲染模式
条件渲染优化
function UserGreeting({ user }) {
// 使用 && 时注意 falsy 值
return (
<div>
{user && <h1>欢迎, {user.name}</h1>}
{user ? <Dashboard /> : <Login />}
</div>
);
}
列表渲染优化
function ItemList({ items }) {
return (
<ul>
{items.map(item => (
<Item
key={item.id} // 使用稳定的 ID,不要用 index
item={item}
/>
))}
</ul>
);
}
使用 Fragment 减少嵌套
function DefinitionList({ items }) {
return (
<dl>
{items.map(item => (
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.definition}</dd>
</Fragment>
))}
</dl>
);
}
小结
本章我们学习了 React 的高级特性:
- Portals:将组件渲染到 DOM 树的其他位置
- Error Boundary:捕获子组件的错误并显示备用 UI
- Suspense:处理异步组件的加载状态
- Strict Mode:开发环境下的代码质量检查工具
- Context 高级用法:动态 Context、嵌套 Provider 和性能优化
练习
- 使用 Portals 实现一个全局通知组件
- 创建一个错误边界组件,支持自定义错误显示和错误上报
- 使用 Suspense 和 React.lazy 实现路由级别的代码分割
- 在项目中启用严格模式,检查并修复发现的问题