React中常用的hook函数(二)——useMemo和useCallback
React中常用的hook函数(一)——useState和useEffect_usestate useeffect-CSDN博客https://blog.csdn.net/Mrs_Lupin/article/details/142905749?spm=1001.2014.3001.5502
一、useMemo
1.作用:
在组件每次重新渲染的时候缓存计算的结果,一般用于消耗非常大的计算,比如n特别大时计算斐波那契数列
2.需求:
count1和count2状态都位于组件内部,无论哪个改变都会引发组件重新渲染,造成浪费。我们想只让count1发生变化时,fn才会重新执行,达到一个缓存的目的
3.语法:
useMemo(() => {
//根据count1返回计算的结果
}, [count1])
4.示例
import { useMemo, useState } from "react"
// 计算斐波那契数列之和
function fib (n) {
console.log('计算函数执行了')
if (n < 3)
return 1
return fib(n - 2) + fib(n - 1)
}
function App () {
const [count1, setCount1] = useState(0)
const result = useMemo(() => {
// 返回计算得到的结果
return fib(count1)
}, [count1])
// const result = fib(count1)
const [count2, setCount2] = useState(0)
console.log('组件重新渲染了')
return (
<div className="App">
this is app
<button onClick={() => setCount1(count1 + 1)}>change count1: {count1}</button>
<button onClick={() => setCount2(count2 + 1)}>change count2: {count2}</button>
{result}
</div>
)
}
export default App
二、React.memo
1.React组件默认的渲染机制:
只要父组件重新渲染子组件就会重新渲染
import { memo, useState } from "react"
function Son () {
console.log('我是子组件,我重新渲染了')
return <div>this is son</div>
}
function App () {
const [count, setCount] = useState(0)
return (
<div className="App">
<button onClick={() => setCount(count + 1)}>+{count}</button>
<Son />
</div>
)
}
export default App
2.作用:
允许组件在Props没有改变的情况下跳过渲染,缓存组件
3.基本语法:
经过memo函数包裹生成的缓存组件作为子组件,只有在props发生变化时才会重新渲染
4.示例:
import { memo, useState } from "react"
const MemoSon = memo(function Son () {
console.log('我是子组件,我重新渲染了')
return <div>this is son</div>
})
function App () {
const [count, setCount] = useState(0)
return (
<div className="App">
<button onClick={() => setCount(count + 1)}>+{count}</button>
<MemoSon />
</div>
)
}
export default App
拓展:props比较机制说明
在使用memo缓存组件之后,React会对每一个prop使用Object.is比较新值和老值,返回true,表示没有变化
prop为简单类型,比较的是数值;prop为引用类型,比较的是新值和旧值的引用是否相等,即便在组件内两次声明的数组或者对象值一模一样,但是组件重新渲染时又会重新生成新的引用
但是可以保证这个引用稳定 --使用useMemo缓存这个数据
const list = useMemo(() => {
return [1, 2, 3]
},[])
三、useCallback
1.作用:
在组件多次重新渲染的时候缓存函数
2.背景:
父子通信时,通过prop传递函数,useCallback使得这个函数稳定,不会重新渲染子组件
3.基本用法:
const changeHandler = useCallback((value) => console.log(value), [])
4.示例:
import { memo, useCallback, useState } from "react"
const Input = memo(function Input ({ onChange }) {
console.log('子组件重新渲染了')
return <input type="text" onChange={(e) => onChange(e.target.value)} />
})
function App () {
// 传给子组件的函数
const changeHandler = useCallback((value) => console.log(value), [])
// 触发父组件重新渲染的函数
const [count, setCount] = useState(0)
return (
<div className="App">
{/* 把函数作为prop传给子组件 */}
<Input onChange={changeHandler} />
<button onClick={() => setCount(count + 1)}>{count}</button>
</div>
)
}
export default App