React 高级特性与最佳实践

在掌握了 React 的基础知识后,我们可以进一步探索 React 的高级特性和最佳实践。这些特性将帮助你构建更高效、可维护和可扩展的 React 应用。本文重点介绍 Hooks、Context、Refs 和高阶组件等核心高级特性。

1. Hooks:函数组件的强大工具

Hooks 是 React 16.8 引入的新特性,允许你在函数组件中使用状态和其他 React 特性。

useState

useState 用于在函数组件中添加状态。

复制代码
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
useEffect

useEffect 用于在函数组件中执行副作用操作(如数据获取、订阅等)。

复制代码
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
2. Context:跨组件传递数据

Context 提供了一种在组件树中传递数据的方法,而不必手动在每个层级传递 props。

复制代码
const ThemeContext = React.createContext('light');

function ThemedButton() {
  return (
    <ThemeContext.Consumer>
      {theme => <button className={theme}>I am styled by theme context!</button>}
    </ThemeContext.Consumer>
  );
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}
3. Refs:访问 DOM 节点

Refs 提供了一种访问 DOM 节点或 React 元素的方式。

复制代码
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  componentDidMount() {
    this.myRef.current.focus();
  }

  render() {
    return <input type="text" ref={this.myRef} />;
  }
}
4. 高阶组件(HOC):复用组件逻辑

高阶组件是一个函数,接受一个组件并返回一个新的组件。它用于复用组件逻辑。

复制代码
function withSubscription(WrappedComponent, selectData) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        data: selectData(DataSource, props)
      };
    }

    componentDidMount() {
      DataSource.addChangeListener(this.handleChange);
    }

    componentWillUnmount() {
      DataSource.removeChangeListener(this.handleChange);
    }

    handleChange = () => {
      this.setState({
        data: selectData(DataSource, this.props)
      });
    }

    render() {
      return <WrappedComponent data={this.state.data} {...this.props} />;
    }
  };
}
5. 渲染属性(Render Props):共享代码

渲染属性是一种在组件之间共享代码的技术,通过一个值为函数的 prop 来实现。

复制代码
class DataProvider extends React.Component {
  state = {
    data: 'Some data'
  };

  render() {
    return this.props.render(this.state);
  }
}

function App() {
  return (
    <DataProvider render={data => (
      <h1>{data}</h1>
    )}/>
  );
}
6. React Router:实现路由

React Router 是一个用于在 React 应用中实现路由的库。

复制代码
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </Switch>
    </Router>
  );
}
7. Redux:状态管理

Redux 是一个状态管理库,通常与 React 一起使用。它提供了一个全局的状态容器,使得状态管理更加可预测和可维护。

javascript 复制代码
import { createStore } from 'redux';
import { Provider, connect } from 'react-redux';

// Action
const increment = () => ({ type: 'INCREMENT' });

// Reducer
const counter = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    default:
      return state;
  }
};

// Store
const store = createStore(counter);

// Component
function Counter({ count, increment }) {
  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

// Connect
const mapStateToProps = state => ({ count: state });
const mapDispatchToProps = { increment };
const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);

// App
function App() {
  return (
    <Provider store={store}>
      <ConnectedCounter />
    </Provider>
  );
}
8. React Testing:测试组件

React 提供了测试工具和库来测试组件的行为和输出。

复制代码
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () => {
  render(<App />);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});
9. React Portals:渲染到 DOM 层次结构之外

Portals 提供了一种将子节点渲染到父组件 DOM 层次结构之外的 DOM 节点的方式。

复制代码
function Modal({ children }) {
  return ReactDOM.createPortal(
    <div className="modal">
      {children}
    </div>,
    document.getElementById('modal-root')
  );
}
10. Error Boundaries:捕获错误

错误边界是 React 组件,用于捕获子组件树中的 JavaScript 错误,并显示备用 UI。

复制代码
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}
11. React Fragments:分组子元素

Fragments 允许你将多个子元素分组,而无需向 DOM 添加额外的节点。

复制代码
function Columns() {
  return (
    <React.Fragment>
      <td>Hello</td>
      <td>World</td>
    </React.Fragment>
  );
}
12. React.memo:优化渲染性能

React.memo 是一个高阶组件,用于优化函数组件的渲染性能,避免不必要的重新渲染。

复制代码
const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});
13. useReducer:复杂状态逻辑

useReduceruseState 的替代方案,适用于复杂的状态逻辑。

复制代码
const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </>
  );
}
14. useCallback 和 useMemo:性能优化

useCallbackuseMemo 用于优化函数组件的性能。

useCallback
javascript 复制代码
const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);
useMemo
javascript 复制代码
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
15. React.lazy 和 Suspense:动态加载组件

React.lazy 允许你动态加载组件,Suspense 用于在组件加载时显示备用内容。

javascript 复制代码
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <OtherComponent />
    </React.Suspense>
  );
}
16. React.StrictMode:突出潜在问题

React.StrictMode 是一个用于突出显示应用中潜在问题的工具。

javascript 复制代码
function App() {
  return (
    <React.StrictMode>
      <div>
        <ComponentOne />
        <ComponentTwo />
      </div>
    </React.StrictMode>
  );
}
17. React 18 新特性

React 18 引入了并发渲染、自动批处理、新的根 API 等新特性。

javascript 复制代码
import { createRoot } from 'react-dom/client';

const container = document.getElementById('root');
const root = createRoot(container);
root.render(<App />);
结语

本文深入探讨了 React 的高级特性,包括Hooks、Context、Refs、高阶组件、渲染属性、路由管理和状态管理、路由管理、状态管理、测试、Portals、错误边界和性能优化工具。通过掌握这些技术,你将能够构建更高效、可维护和可扩展的 React 应用。继续学习和实践,你将充分发挥 React 的强大功能!

相关推荐
全干engineer4 分钟前
Web3-Web3.js核心操作:Metamask、合约调用、事件订阅全指南
开发语言·javascript·web3·区块链·智能合约
Leyla17 分钟前
你不知道的 parseInt 方法
javascript·面试
米花丶19 分钟前
前端 Service Worker最佳实践(上):高效的预缓存与运行时缓存方案
前端
困困的果果头31 分钟前
【vue + element】el-table支持多层级合并列
前端·javascript·vue.js·elementui
GISer_Jing32 分钟前
React前端与React Native移动端开发须知差异
前端·react native·react.js
EndingCoder33 分钟前
React Native 与后端协同开发指南
javascript·react native·react.js
G等你下课37 分钟前
被低估的 CSS 核心!盒子模型如何撑起万亿级网页?
前端·css
只喜欢赚钱的棉花没有糖38 分钟前
从loader和plugin开始了解webpack
前端·webpack
前端日常开发39 分钟前
0 费用使用免费服务器部署 NestJS 项目
前端·后端