跳到主要内容

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 的高级特性:

  1. Portals:将组件渲染到 DOM 树的其他位置
  2. Error Boundary:捕获子组件的错误并显示备用 UI
  3. Suspense:处理异步组件的加载状态
  4. Strict Mode:开发环境下的代码质量检查工具
  5. Context 高级用法:动态 Context、嵌套 Provider 和性能优化

练习

  1. 使用 Portals 实现一个全局通知组件
  2. 创建一个错误边界组件,支持自定义错误显示和错误上报
  3. 使用 Suspense 和 React.lazy 实现路由级别的代码分割
  4. 在项目中启用严格模式,检查并修复发现的问题