一起养成写作习惯!这是我参与「掘金日新计划 · 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'))
使用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'))
在看效果如下:
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'))
这样,父组件更新就不会导致子组件更新了