Skip to main content

hooks使用之useCallback

useCallback是用来长期稳定的维护某个函数引用的, 他会将函数创建后的引用保存, 当函数组件下次重新渲染时, 他会直接返回之前保存的引用,而不是重新创建引用

每次组件的重新渲染都意味着内部所有引用值都会被重新构建 每一次渲染可以视作定格(时间切片), 因为每次渲染会被重新构建 函数的引用也会重新执行---会导致性能浪费

示例:1

function StudentList () {
const [studentList, setStudentList] = useState([])
const {loading, executeRequest} = useRequestLoadingDispatcher()

// useCallback 只在创建函数引用的时候使用
// 1, 第一个参数你要对应赋值给变量的函数体 [函数声明]
// 2. 第二个参数依赖项, 当一来项发生了变动以后 对应的函数应用会被重新生成
const fetchResponse = useCallback(async() => {
// 否则你拿到的还是上一个时间切片的函数
executeRequest(async() => {
const res = await getStudentList()
setStudentList(res.data)
})
}, [executeRequest])

// 反正需要用到函数的地方你都用useCallback包起来

useEffect(() => {
executeRequest(fetchResponse)
},[])

return (
<div>
{loading ? (<div>正在加载中...</div>) : studentList.map(item => (<StudentItem {...item} key={item.name}/>))}
</div>
)
}

示例:2


import { useCallback, useState } from "react";


export default function Counter() {
const [count,setCount] = useState(0)

const addCount = useCallback(() => {
setCount(prev => prev+1)
},[])



// 由于没有给getCountValue做任何的性能处理, 每次组件重新渲染他都毫无例外的参与了引用何重新构建

// 不给任何依赖的后果, 是不是使用拿的是厚此渲染的时间切片: 0
const getCountValue = useCallback(() => {
console.log('最新的countvalue', count) // 每一次count导致的重新渲染都导致了getCountValue的值重新刷新
}, [count])

return (
<div>
<span>{count}</span>
<button onClick={addCount}>add Count</button>
<button onClick={getCountValue}>get Count</button>
</div>
)
}