React 笔记(性能优化篇)

1. useState

useState 的参数可以传入一个函数,这样就可以避免每次更新时都重新创建一个对象。

import React, { useState } from 'react';

function App() {
    const [expensiveValue, setExpensiveValue] = useState(() => {
        console.log('初始化 state');
        return Array(1000000).fill(0).map(() => Math.random())
    })

    return (
        <div>
            <p>数组长度: {expensiveValue.length}</p>
            <button onClick={() => setExpensiveValue([...expensiveValue, Math.random()])}>添加一个随机数</button>
        </div>
    )
}

export default App;

上述代码中,console.log 只会在首次渲染时执行一次,后续更新时不会重新执行。

2. useMemo

使用 useMemo 缓存比较消耗性能的操作,比如生成二维码,避免在每次渲染时都进行重复的计算。

import React, { useMemo, useState } from 'react';
import QRCode from 'qrcode.react';

function App() {
  const [text, setText] = useState("Hello, world!");

  const memoizedQRCode = useMemo(() => {
    return <QRCode value={text} />;
  }, [text]); // 只有当 text 改变时才重新生成二维码

  return (
    <div>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
      {memoizedQRCode}
    </div>
  );
}

export default App;

上述代码中,memoizedQRCode 只有在 text 改变时才会重新生成二维码,从而避免每次渲染时都重新生成二维码。

3. useCallback

使用 useCallback 缓存函数,避免在每次渲染时都重新创建函数。

import React, { useState, useCallback } from 'react';

function IncrementButton({ onClick }) {
  console.log('渲染 IncrementButton');
  return <button onClick={onClick}>Increment</button>;
}

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

  const increment = useCallback(() => {
    setCount(count + 1);
  }, [count]); // 缓存函数,只有 count 改变时才重新创建

  return (
    <div>
      <p>Count: {count}</p>
      <IncrementButton onClick={increment} />
    </div>
  );
}

export default App;

上述代码中,使用 useCallback 缓存了 increment 函数,从而避免在每次渲染时都重新创建函数。

4. memo

使用 memo 缓存组件,避免在每次渲染时都重新渲染组件,只有当组件的 props 改变时才会重新渲染组件。

import React, { memo } from 'react';

function MyComponent({ data }) {
    console.log('渲染 MyComponent');
    return <div>{data}</div>;
}

const MemoizedComponent = memo(MyComponent);

function App() {
    return <MemoizedComponent data="Hello, world!" />
}

export default App;

上述代码中,MemoizedComponent 只有在 data 改变时才会重新渲染组件,从而避免每次渲染时都重新渲染组件。

5. useRef

使用 useRef 缓存 DOM 元素,避免在每次渲染时都重新获取 DOM 元素。

import React, { useRef } from 'react';

function App() {
    const inputRef = useRef(null);

    return <input ref={inputRef} />
}

export default App;

上述代码中,inputRef 只会在首次渲染时创建,后续更新时不会重新创建。

6. 路由懒加载

使用 React.lazySuspense 进行路由懒加载,避免在每次渲染时都加载组件,只有当路由改变时才会加载组件,同时 Suspense 组件可以提供 fallback 组件,避免在加载组件时出现白屏。

import React, { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));


function App() {
    return (
        <Router>
            <Suspense fallback={<div>Loading...</div>}>
                <Switch>
                    <Route path="/" exact component={Home} />
                <Route path="/about" component={About} />
                </Switch>
            </Suspense>
        </Router>
    );
}

export default App;

上述代码中,HomeAbout 只有在路由改变时才会加载组件;在打包时,HomeAbout 会被打包成单独的文件,减少 bundle 文件的大小,提高首屏加载速度。

posted @ 2024-11-26 16:52  to人间值得  阅读(40)  评论(0)    收藏  举报