14. React 项目开发 的 进阶模式

1 阅读3分钟

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(支持 SSRSSG)。

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 设计的 状态管理库