函数名: useCallback
用于得到一个固定引用值的函数,通常用它进行性能优化
该函数有两个参数:
1.函数,useCallBack会固定该函数的引用,只要依赖项没有发生改变,则始终返回之前函数的地址
2.数组,记录依赖项
(类似于useEffect)
该函数返回:引用相对固定的函数地址
应用场景:
import React, { useState } from 'react'
class Test extends React.PureComponent {
render() {
console.log("Test Render")
return <div>
<h1>{this.props.text}</h1>
<button onClick={this.props.onClick}>改变文本</button>
</div>
}
}
const Parent = () => {
console.log("Parent Render")
const [txt, setTxt] = useState(123)
const [n, setN] = useState(0)
return (
<div>
<Test text={txt} onClick={() => {
setTxt(123)
}}></Test>
<input type="number"
value={n}
onChange={
e => {
setN(parseInt(e.target.value))
}
}></input>
</div>
)
}
const App = () => {
return (
<div>
<Parent />
</div>
)
}
export default App
理论上来说,Test作为纯组件,只有在传入发生改变的时候才会重新渲染,当点击改变文本的按钮时setTxt所更改的值与本身Txt的值相同,所以Test组件不会重新渲染,不会打印Test Render
问题所在就是,当Parent组件中的其他值发生改变的时候,Parent组件便会重新渲染,而Test组件中Txt的值虽然没有改变,但传入的() => {setTxt(123)}作为方法对象,会创建一个新的地址栈,两次地址的指向不同了,所以会认为传入的值发生了改变,所以Test组件发生了重新渲染
这样的渲染浪费了不必要的性能,所以useCallback就是用来解决这一问题的
import React, { useState,useCallback } from 'react'
class Test extends React.PureComponent {
render() {
console.log("Test Render")
return <div>
<h1>{this.props.text}</h1>
<button onClick={this.props.onClick}>改变文本</button>
</div>
}
}
const Parent = () => {
console.log("Parent Render")
const [txt, setTxt] = useState(123)
const [n, setN] = useState(0)
const hhh = useCallback(()=> {
setTxt(223)
},[])
return (
<div>
<Test text={txt} onClick={hhh}></Test>
<input type="number"
value={n}
onChange={
e => {
setN(parseInt(e.target.value))
}
}></input>
</div>
)
}
const App = () => {
return (
<div>
<Parent />
</div>
)
}
export default App
这样当改变n的值时Test组件就不会跟着渲染啦