关于 react-hooks 一个可能跟性能有关的疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
cl903254852
V2EX    程序员

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

  •  
  •   cl903254852 2020-05-30 10:28:55 +08:00 4083 次点击
    这是一个创建于 1960 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近从 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 时,对于这些是怎么处理的?
    • 有没有其他会影响性能的地方?

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

    21 条回复    2020-05-30 22:00:29 +08:00
    CodingNaux
        1
    CodingNaux  
       2020-05-30 10:39:30 +08:00 via iPhone
    看文档
    lbw
        2
    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
        3
    whe  
       2020-05-30 10:44:36 +08:00   1
    useMemo & useCallback
    duan602728596
        4
    duan602728596  
       2020-05-30 10:48:40 +08:00 via iPhone
    可以用 useMemo 和 useCallback,让变量或者函数只在依赖变化时重新计算。
    性能的话,大部分项目还没有复杂到必须进行性能优化。
    CodingNaux
        5
    CodingNaux  
       2020-05-30 10:53:37 +08:00 via iPhone
    有些函数都没必要用 useCallback 包裹,丢在组件外面就可以了
    CodingNaux
        6
    CodingNaux  
       2020-05-30 10:55:12 +08:00 via iPhone
    有些简单计算没必要用 useMemo 包裹
    zhuangzhuang1988
        7
    zhuangzhuang1988  
       2020-05-30 10:58:05 +08:00
    react 就这样 引入 hook 心智负担变得更大了

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

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

    其它的,在了解 hooks 之前先了解一下 function component 更好
    ChefIsAwesome
        16
    ChefIsAwesome  
       2020-05-30 13:02:30 +08:00
    有影响。大不大看你组件复杂不复杂。
    sucai
        17
    sucai  
       2020-05-30 14:04:34 +08:00
    在外面用 react.memo 包一下 Demo
    dcatfly
        18
    dcatfly  
       2020-05-30 14:19:43 +08:00
    建议先完整阅读一遍 react hooks 相关的文档,你说的这些问题文档都有解
    myCupOfTea
        19
    myCupOfTea  
       2020-05-30 14:22:42 +08:00
    有影响,不过不是太太太复杂的系统可以忽略不计,所以才有了 useRef useMemo useCallback
    limi58
        20
    limi58  
       2020-05-30 14:24:10 +08:00
    一般重复定义只是定义而已,性能消耗忽略不计,并没有复杂运算,如果有,useMemo useCallback 直接上场
    royzxq
        21
    royzxq  
       2020-05-30 22:00:29 +08:00
    合理利用 useMemo useCallback
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     6104 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 06:19 PVG 14:19 LAX 23:19 JFK 02:19
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86