React函数式组件怎样优化,从哪些方面入手

Admin 2022-10-20 群英技术资讯 303 次浏览

关于“React函数式组件怎样优化,从哪些方面入手”的知识有一些人不是很理解,对此小编给大家总结了相关内容,具有一定的参考借鉴价值,而且易于学习与理解,希望能对大家有所帮助,有这个方面学习需要的朋友就继续往下看吧。

优化思路

主要优化的方向有2个:

  1. 减少重新 render 的次数。因为在 React 里最重(花时间最长)的一块就是 reconction(简单的可以理解为 diff),如果不 render,就不会 reconction。
  2. 减少计算的量。主要是减少重复计算,对于函数式组件来说,每次 render 都会重新从头开始执行函数调用。

在使用类组件的时候,使用的 React 优化 API 主要是:shouldComponentUpdate和 PureComponent

那么在函数式组件中,我们怎么做性能优化?主要用到下面几个方法去优化

  • React.memo
  • useCallback
  • useMemo

React.memo

看个例子:

我们在父组件中放一个按钮用于修改子标题,并引入Child子组件

可以看到,第一次进来子组件打印了console.log('我是子组件')

当点击修改子标题,Child子组件也打印了,造成了不必要的重复渲染次数

?
//父组件 import {useState} from 'react'   import Child from "./Child" ; const Index = ()=>{      const [subTitle, setSubTitle] = useState( '我是子标题' )      const updateSubTitle = ()=>{        setSubTitle( '修改子标题' )      }      return (        <div>          <div>函数式组件性能优化</div>          <div>{subTitle}</div>          <button onClick={updateSubTitle}>修改子标题</button>          <Child/>        </div>      );    }       export default Index;     //子组件Child.js const Child = ()=>{      console.log( '我是子组件' )      return (          <div>我是子组件</div>      ) } export default Child

优化一下,使用React.memo包裹子组件

?
import React from "react" ;   const Child = ()=>{      console.log( '我是子组件' )      return (          <div>我是子组件</div>      ) } export default React.memo(Child)

再观察一下,发现Child子组件没有重复渲染了

useCallback

这里我们再改造一下,给Child子组件添加一个onclick事件,然后点击修改子标题按钮,发现我们的Child子组件又重新渲染了,这里主要是因为修改子标题的时候handlerClick函数重新渲染变化,造成子组件重新渲染

?
// 父组件 const Index = ()=>{      const [subTitle, setSubTitle] = useState( '我是子标题' )      const updateSubTitle = ()=>{        setSubTitle( '修改子标题' )      }      const handlerClick = ()=>{        console.log( '子组件点击' )      }      return (        <div>          <div>函数式组件性能优化</div>          <div>{subTitle}</div>          <button onClick={updateSubTitle}>修改子标题</button>          <Child onClick={handlerClick}/>        </div>      );    }   // Child子组件 const Child = (props)=>{      console.log( '我是子组件' )      return (          <div>              <div>我是子组件</div>              <button onClick={props.onClick}>子组件按钮</button>          </div>      ) } export default React.memo(Child)

优化一下,使用useCallback包裹处理子组件的handlerClick函数,再次点击updateSubTitle修改子标题,发现Child子组件没有重新再渲染

?
// 父组件 const Index = ()=>{      const [subTitle, setSubTitle] = useState( '我是子标题' )      const updateSubTitle = ()=>{        setSubTitle( '修改子标题' )      }      const handlerClick = useCallback(()=>{        console.log( '子组件点击' )      },[])        return (        <div>          <div>函数式组件性能优化</div>          <div>{subTitle}</div>          <button onClick={updateSubTitle}>修改子标题</button>          <Child onClick={handlerClick}/>        </div>      );    }       export default Index;

这里关于useCallback的用法

?
const callback = () => {    doSomething(a, b); }   const memoizedCallback = useCallback(callback, [a, b])

把函数以及依赖项作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,这个 memoizedCallback 只有在依赖项有变化的时候才会更新。

useMemo

useMemo用于计算结果缓存

我们先看个例子,在之前基础上添加一个calcCount计算函数,然后点击updateSubTitle更新子标题,发现calcCount重新计算了,也就是每次渲染都会造成重复计算,如果是计算量比较大的情况下,会极大的影响性能

?
// 父组件 const Index = ()=>{      const [subTitle, setSubTitle] = useState( '我是子标题' )      const updateSubTitle = ()=>{        setSubTitle( '修改子标题' )      }      const handlerClick = useCallback(()=>{        console.log( '子组件点击' )      },[])        const calcCount = ()=>{               let totalCount = 0        for (let i=0;i<10000;i++){          totalCount+=i        }        console.log( 'totalCount' ,totalCount)        return totalCount      }        const count = calcCount()        return (        <div>          <div>函数式组件性能优化</div>          <div>{subTitle}</div>          <button onClick={updateSubTitle}>修改子标题</button>          <div>count:{count}</div>          <Child onClick={handlerClick}/>        </div>      );    }

优化一下,使用useMemo缓存计算结果,我们再次点击updateSubTitle修改子标题按钮,可以发现calcCount函数不再重复计算

?
const calcCount = ()=>{             let totalCount = 0       for (let i=0;i<10000;i++){         totalCount+=i       }       console.log( 'totalCount' ,totalCount)       return totalCount     }       const count = useMemo(calcCount,[])

最后,需要注意的是不能盲目的使用useMemo,要根据具体的场景,比如对于一个数据计算量比较大,那么使用是比较适用的,而对于普通的一些值得计算,可以不使用,因为本身useMemo也是会消耗一些性能,盲目使用反而会适得其反


到此这篇关于“React函数式组件怎样优化,从哪些方面入手”的文章就介绍到这了,更多相关React函数式组件怎样优化,从哪些方面入手内容,欢迎关注群英网络,小编将为大家输出更多高质量的实用文章! 群英智防CDN,智能加速解决方案

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

猜你喜欢

成为群英会员,开启智能安全云计算之旅

立即注册
专业资深工程师驻守
7X24小时快速响应
一站式无忧技术支持
免费备案服务
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
在线客服
微信公众号
返回顶部
返回顶部 返回顶部
在线客服
在线客服