react优化性能

192 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

唉,不知道为啥react要这么多更新~~~ 性能优化的主要方向就是减少更新

减少不必要的更新

有如下不必要的更新场景:

1. 父包含子组件,子组件没有接收任何的外部属性

此时如果父组件更新了,子组件也会更新,这里子组件的更新就是没有必要的更新。原因很简单呀:它没有理由去更新呀,它自己的状态没有任何变化。

优化前

代码如下:

import React, { useState } from 'react'
import ReactDOM from 'react-dom'

function F () {
  const [count, setCount] = useState(0)
  return (<div>
        <p onClick={() => setCount(count + 1)}>父组件的数据:{count}。点击可更新</p>
        <Son></Son>
    </div>)
}

function Son () {
  return <div>子组件:{Math.random()}</div>
}

ReactDOM.render(<F/>, document.getElementById('root'))


image.png

使用React.memo做优化

代码如下:

/* eslint-disable react/display-name */
import React, { useState } from 'react'
import ReactDOM from 'react-dom'

function F () {
  const [count, setCount] = useState(0)
  return (<div>
        <p onClick={() => setCount(count + 1)}>父组件的数据:{count}。点击可更新</p>
        <Son></Son>
    </div>)
}

const Son = React.memo(() => {
  return <div>子组件:{Math.random()}</div>
})

ReactDOM.render(<F/>, document.getElementById('root'))

在看效果如下: image.png

2.父包含子组件,且传入一个函数给子组件

此时如果父组件更新了,就算是对子组件使用了React.memo,子组件也会更新。 这里子组件的更新就是没有必要的更新。原因很简单呀:父组件更新时,它传给子的函数没有变化呀

优化前

/* eslint-disable react/display-name */
import React, { useState } from 'react'
import ReactDOM from 'react-dom'

function F () {
  const [count, setCount] = useState(0)
  const someFn = () => {}
  return (<div>
        <p onClick={() => setCount(count + 1)}>父组件的数据:{count}。点击可更新</p>
        <Son someFn={someFn}></Son>
    </div>)
}

const Son = React.memo(() => {
  return <div>子组件:{Math.random()}</div>
})

ReactDOM.render(<F/>, document.getElementById('root'))

使用useCallback做优化

格式是: const 新函数 = useCallback(原函数,[...依赖项])。当依赖项的内容变化后,才会产生另一新函数。

/* eslint-disable react/display-name */
import React, { useState, useCallback } from 'react'
import ReactDOM from 'react-dom'

function F () {
  const [count, setCount] = useState(0)
  // const someFn = () => {}
  // 使用useCallback对原someFn做优化
  const someFn = useCallback(() => {}, [])
  return (<div>
        <p onClick={() => setCount(count + 1)}>父组件的数据:{count}。点击可更新</p>
        <Son someFn={someFn}></Son>
    </div>)
}

const Son = React.memo(() => {
  return <div>子组件:{Math.random()}</div>
})

ReactDOM.render(<F/>, document.getElementById('root'))

这样,父组件更新就不会导致子组件更新了