关于 react-hooks 一个可能跟性能有关的疑问

2020-05-30 10:28:55 +08:00
 cl903254852

最近从 class component 切换到 react hooks 写法.

比如下面这个例子:


function Demo(){
    const [count, setCount] = useState(0);
    
    useEffect(()=>{
    
    },[])
    
    const func_1 = () => { //... }
    const func_2 = () => { //... }
    const func_3 = () => { //... }
    // 这里还有 const 其他变量...
    
    return <div/>
}

我发现,只要状态改变,Demo 这个函数就会重新执行一次, 也就是说定义在 Demo 里的所有变量每次 render 时都会重新定义, 这样不会有性能问题吗?

而且 Demo 这个函数中返回了组件 jsx,它不就是 class component 里的 render 方法吗? 相当于我这些定义的变量是在 render 方法里定义的?

鄙人也是刚入手 react hooks , 望大家指点一二,Thanks♪(・ω・)ノ

3352 次点击
所在节点    程序员
21 条回复
CodingNaux
2020-05-30 10:39:30 +08:00
看文档
lbw
2020-05-30 10:43:57 +08:00
1. 示例代码的 Demo 函数就是函数式组件,那么在组件 props 变化或 hook 状态改变,必然要通过调用整个 Demo 函数来产生新的 vnode,进而更新 dom,因为函数式组件本身就是一个函数!!它只有通过重新调用才能产生新的副作用,而不像 class 可通过调用 render
2. 对应的你说的因每次调用 Demo 而产生的性能问题,react 官方通过 hook 的第二个参数(即上文 useEffect 的空数组)来实现在每次 Demo 函数调用期间实现使用缓存,而不是每次都重新计算,这也是 hook 的特性之一
3. 其他比如 useCallback useMemo 等 hook 均是通过第二个参数数组来申明 hook 的依赖,进而实现复用缓存
4. class 中 render 起到的作用就是调用函数式组件的调用结果——产生新的 vnode,进而通过协调算法更新视图。class 组件和函数式组件的本质区别之一就是 class 自带生命周期和状态
whe
2020-05-30 10:44:36 +08:00
useMemo & useCallback
duan602728596
2020-05-30 10:48:40 +08:00
可以用 useMemo 和 useCallback,让变量或者函数只在依赖变化时重新计算。
性能的话,大部分项目还没有复杂到必须进行性能优化。
CodingNaux
2020-05-30 10:53:37 +08:00
有些函数都没必要用 useCallback 包裹,丢在组件外面就可以了
CodingNaux
2020-05-30 10:55:12 +08:00
有些简单计算没必要用 useMemo 包裹
zhuangzhuang1988
2020-05-30 10:58:05 +08:00
react 就这样 引入 hook 心智负担变得更大了

vue 相对好很多, 不过也有坑, 很容易组件就不响应式了
pyplayer
2020-05-30 11:43:25 +08:00
lancelock
2020-05-30 11:47:31 +08:00
最近也在写 hooks 。优点是很明显,但感觉并非完美方案
zhuweiyou
2020-05-30 11:49:37 +08:00
太小看 现代电脑 /手机了,一般的场景,还没到性能优化的地步。有这功夫还不如想想,怎么优化一下用户体验。
fancy2020
2020-05-30 12:03:58 +08:00
变量定义本身的性能消耗可以忽略不计的,如果你的变量定义依赖一个复杂运算的结果,那么这个运算可以用 useMemo 来缓存结果,在依赖不变的情况下不会重复执行计算过程。
WeiShurong
2020-05-30 12:30:32 +08:00
楼上都说的很好了。补充一下,如果你真的很在乎 render 的次数,你可以使用 React.memo 包裹函数式组件,这样只有 prop 变更时,才会调用(和 shouldComponentUpdate 一样)
joesonw
2020-05-30 12:32:00 +08:00
1. 有改变只会是 vdom 改变, 之后还要做 diff 的. 影响性能是在是忽略不计了.
2. hook 本身有缓存机制, 善用. 例如回调用 useCallback 的话, 只在 dependency list 变化的情况下才会重新取值(取函数)
love
2020-05-30 12:36:21 +08:00
别说会重新执行函数了,更大的坑是小心别引用了旧变量。

所以我觉得 vue 版 hooks 是更优设计
seki
2020-05-30 12:46:51 +08:00
虚拟 dom 计算这一层是纯 js 的,一般来讲对性能影响不大。改变 dom 对性能的影响是更主要的

其它的,在了解 hooks 之前先了解一下 function component 更好
ChefIsAwesome
2020-05-30 13:02:30 +08:00
有影响。大不大看你组件复杂不复杂。
sucai
2020-05-30 14:04:34 +08:00
在外面用 react.memo 包一下 Demo
dcatfly
2020-05-30 14:19:43 +08:00
建议先完整阅读一遍 react hooks 相关的文档,你说的这些问题文档都有解
myCupOfTea
2020-05-30 14:22:42 +08:00
有影响,不过不是太太太复杂的系统可以忽略不计,所以才有了 useRef useMemo useCallback
limi58
2020-05-30 14:24:10 +08:00
一般重复定义只是定义而已,性能消耗忽略不计,并没有复杂运算,如果有,useMemo useCallback 直接上场

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/676892

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX