我用下面的例子做了一个简单的测试,它使用 10k(和 100k)usingCallback
钩子并每 100 毫秒重新渲染一次。看起来数量useCallback
确实很多的时候会影响。看看下面的结果。
具有 10k 个钩子的函数组件:
每次渲染需要 8~12ms。
具有 100k 个钩子的函数组件:
每次渲染需要 25~80 毫秒。
具有 10k 方法的类组件:
每次渲染需要 4~5ms。
具有 100k 方法的类组件:
每次渲染需要 4~6ms。
我也用 1k 示例进行了测试。但是配置文件结果看起来与 10k 的结果几乎相同。
因此,当我的组件使用 100k 钩子而类组件没有显示出明显的差异时,我的浏览器中的惩罚很明显。所以我想只要你没有使用超过 10k 个钩子的组件就可以了。不过,这个数字可能取决于客户端的运行时资源。
测试组件代码:
import React, { useState, useCallback, useEffect } from 'react';
const callbackCount = 10000
const useCrazyCounter = () => {
const callbacks = []
const [count, setCount] = useState(0)
for (let i = 1; i < callbackCount + 1; i++) {
// eslint-disable-next-line
callbacks.push(useCallback(() => {
setCount(prev => prev + i)
// eslint-disable-next-line
}, []))
}
return [count, ...callbacks]
}
const Counter = () => {
const [count, plusOne] = useCrazyCounter()
useEffect(() => {
const timer = setInterval(plusOne, 100)
return () => {
clearInterval(timer)
}}
, [])
return <div><div>{count}</div><div><button onClick={plusOne}>Plus One</button></div></div>
}
class ClassCounter extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
for (let i = 1; i < callbackCount; i++) {
this['plus'+i] = () => {
this.setState(prev => ({
count: prev.count + i
}))
}
}
}
componentDidMount() {
this.timer = setInterval(() => {
this.plus1()
}, 100)
}
componentWillUnmount() {
clearInterval(this.timer)
}
render () {
return <div><div>{this.state.count}</div><div><button onClick={this.plus1}>Plus One</button></div></div>
}
}
const App = () => {
return (
<div className="App">
<Counter/>
{/* <ClassCounter/> */}
</div>
);
}
export default App;