• React.memo()、userMemo 、 userCallbank的区别及使用


    本文是对以下课程的笔记输出,总结的比较简洁,若大家有不理解的地方,可以通过观看课程进行详细学习;

    React81_React.memo_哔哩哔哩_bilibili

    React76_useEffect简介_哔哩哔哩_bilibili

    React136_useMemo_哔哩哔哩_bilibili

    React.memo()

    性能优化

    1. export default function App() {
    2. console.log('App渲染')
    3. const [count, setCount] = useState(1)
    4. const clickHandler = () => {
    5. setCount(prevState => prevState + 1)
    6. }
    7. // 增加
    8. const test = count % 4 === 0
    9. return (
    10. <div>
    11. <h2>App -- {count}h2>
    12. <button onClick={clickHandler}>增加button>
    13. {/* 改动 */}
    14. <A test={test} />
    15. div>
    16. )
    17. }
    18. const A = React.memo(props => {
    19. console.log('A渲染')
    20. return (
    21. <div>
    22. 我是A组件
    23. {/* 增加 */}
    24. <p>{props.test && 'props.test 为 true'}p>
    25. div>
    26. )
    27. })

    对代码进行解释:

    一开始是false,只有为true的时候,A组件才会重新渲染。

    若不加 React.memo,当APP组件重新渲染时,A组件也会重新渲染。A组件中没有state,甚至连props都没有设置。换言之,A组件无论如何渲染,每次渲染的结果都是相同的,虽然重渲染并不会应用到真实DOM上,但很显然这种渲染是完全没有必要的

    但若对代码进行如下修改,

    这是因为App组件重新渲染的时候,clickHandler也重新创建了,这时传递给子组件的clickHandler和上一次不一样,所以react.memo失效了。

    这个问题可以用useCallback解决。

    useCallback

    1. import React, { useState } from 'react'
    2. export default function App() {
    3. console.log('App渲染')
    4. const [count, setCount] = useState(1)
    5. const clickHandler = () => {
    6. setCount(prevState => prevState + 1)
    7. }
    8. return (
    9. <div>
    10. <h2>App -- {count}h2>
    11. <button onClick={clickHandler}>增加button>
    12. <A clickHandler={clickHandler} />
    13. div>
    14. )
    15. }
    16. const A = React.memo(props => {
    17. console.log('A渲染')
    18. return (
    19. <div>
    20. 我是A组件
    21. <button onClick={props.clickHandler}>A组件的增加button>
    22. div>
    23. )
    24. })

     用法介绍

    /*
    *   useCallback()
    *        这个hook会缓存方法的引用
    *       参数:
    *           1. 回调函数
    *           2. 依赖数组
    *               - 当依赖数组中的变量发生变化时,回调函数才会重新创建
    *               - 如果不指定依赖数组,回调函数每次都会重新创建
    *               - 一定要将回调函数中使用到的所有变量都设置到依赖数组中
    *                   除了(setState)
    * */

    引出useCallback

    1. import React, { useState, useCallback } from 'react'
    2. export default function App() {
    3. console.log('App渲染')
    4. const [count, setCount] = useState(1)
    5. // 增加
    6. const [num, setNum] = useState(1)
    7. const clickHandler = useCallback(() => {
    8. setCount(prevState => prevState + num)
    9. // 增加
    10. setNum(prevState => prevState + 1)
    11. }, [num])
    12. return (
    13. <div>
    14. <h2>App -- {count}h2>
    15. <button onClick={clickHandler}>增加button>
    16. <A clickHandler={clickHandler} />
    17. div>
    18. )
    19. }
    20. const A = React.memo(props => {
    21. console.log('A渲染')
    22. return (
    23. <div>
    24. 我是A组件
    25. <button onClick={props.clickHandler}>A组件的增加button>
    26. div>
    27. )
    28. })

     界面图

    点击了两次增加后,count变成了预期值4。

    第二个参数一定要加,不然和平常写没有区别 依赖项[]的意思是只有第一次渲染时才会创建,之后都不会重新创建了

    useMemo

    useMemo和useCallback十分相似,useCallback用来缓存函数对象,useMemo用来缓存函数的执行结果。在组件中,会有一些函数具有十分的复杂的逻辑,执行速度比较慢。闭了避免这些执行速度慢的函数返回执行,可以通过useMemo来缓存它们的执行结果,像是这样:

    1. const result = useMemo(()=>{
    2. return 复杂逻辑函数();
    3. },[依赖项])

    useMemo中的函数会在依赖项发生变化时执行,注意!是执行,这点和useCallback不同,useCallback是创建。执行后返回执行结果,如果依赖项不发生变化,则一直会返回上次的结果,不会再执行函数。这样一来就避免复杂逻辑的重复执行。

      React.useEffect(() => {
      //中括号内有参数  可理解为watch  没有参数  可理解为created
      }, [])
    
      //等中括号里的数据变化时  执行该操作  有返回值  这直接在页面中使用  类似于compunted  
      //中括号里没有值时  加载时触发 只走一次
      const useNum=React.useMemo(()=>{
          return num+1
      },[num])  

    参考笔记:Learning-Notes/15【react-Hook (下)】.md at master · dselegent/Learning-Notes · GitHub

  • 相关阅读:
    ssm+vue+elementUI 医院门诊互联电子病历管理信息系统-#毕业设计
    Web开发-GET与POST
    基于安卓android微信小程序的在线考试系统
    Zookeeper - Java API 对节点操作
    【Java】List接口中泛型如何实现
    java 设计模式
    【教3妹学算法-每日3题(2)】去掉最低工资和最高工资后的工资平均值
    封装公共组件中在main.js中通过插件统一注册
    2022年冬pat乙级考试题目及代码解析附部分错误原因
    Linux操作系统常见指令理解(2)
  • 原文地址:https://blog.csdn.net/weixin_48037671/article/details/131037356