当前位置: 首页 > article >正文

react中useRef和useMemo和useCallback

memo : 被memo包裹的组件,会浅层比较 props,不会深度比较,如果浅层比较相同,就不会重新渲染组件

默认是,无论怎么,都会重新渲染一遍子组件,,

useMemo: 包裹一个函数,返回一个值,,只会在监听的状态改变的时候,才会重新执行一遍这个函数

这两个用来避免重新渲染,子组件,,或者重新执行一个复杂的函数,,,在不需要的情况下,,比如说,你的状态改变跟某个子组件没有关系,,就不用触发这个子组件的重新渲染

父组件:

import {useMemo, useState} from "react";
import ChildComponent from "./children/ChildComponent";

function HeheMemo(){

    const [count, setCount] = useState(0)
    const [text, setText] = useState("")


    function expensiveResult(){
        console.log("recalculate...")

        // return Math.random().;
        return Math.floor(Math.random()*1000000)
    }


    const memoizedValueValue = useMemo(()=>expensiveResult(),[count])


    // 只有当count变化的时候,才会重新渲染子组件
    const memoizedChild = useMemo(()=>{
        return <ChildComponent count={count}/>
    },[count])





    return(
        <div>
            <h1>expensive calculation</h1>
            <ChildComponent count={count} />
            <div>count : {count}</div>
            <div>expensive {memoizedValueValue} </div>
            <button onClick={()=>setCount(count+1)}>btn</button>
            <input type="text" onChange={e=>setText(e.target.value)}/>


        </div>
    )
}


export default HeheMemo

子组件:

import React, {memo} from "react";

// interface ChildProps extends React.ComponentProps<any>

interface ChildProps{
    count:number
}

const Child = memo((props:ChildProps)=>{
    console.log("我被渲染了")

    return (
        <div> child component --{props.count} </div>
    )
})



export default Child

useRef

setState 会触发页面的重新渲染,,就会重新执行函数,,,,像那种计时器,如果第二次渲染就变了,,需要保证是同一个定时器,,使用useRef,,
useEffect()只会在依赖变化的时候重新执行,,如果依赖没有变化,他取得就是最开始的那个状态,,,闭包中的函数和变量是静态的,,函数捕获了定义时的变量环境,,后续无法感知变量的变化

import React, {Component, useEffect, useRef, useState} from 'react';

function Hello02() {


    const [text, setText] = useState("")
    function handleClick(){
        console.log("click with text"+text)
    }

    const clickRef = useRef<Function>(null);
    clickRef.current = handleClick

    /**
     * 初次渲染 ===》   clickRef被赋值,,
     * 后续渲染 ===》 setText() ==> 更新状态,触发再次渲染 ==》 clickRef重新被赋值
     *
     *
     * 闭包中的函数和变量是静态的,,函数捕获了定义时的变量环境,,后续无法感知变量的变化
     */

    useEffect(()=>{

      const interval =   setInterval(()=>{
            clickRef.current?.()
        },1000)
        return ()=>clearInterval(interval)
    },[])

    return (
        <div>
            <input type="text" value={text} onChange={e=>setText(e.target.value)}/>
            <button onClick={handleClick}>btn</button>

        </div>
    )
}


export default Hello02;

useState:可以获取之前的状态

    const startTimer = ()=>{
        if (!timeRef.current){
            timeRef.current = window.setInterval(()=>{
                setCount(prevState => prevState+1)
            },1000)
        }
    }
useCallback

父组件在传递回调函数给子组件的时候,,如果父组件更改了状态,重新渲染,,这个函数会被重新创建,返回一个新的函数,,这个新的函数的引用,,让props改变了,导致子组件,,即使使用了 memo,,也会重新渲染

使用 useCallback记忆化回调函数,,这个函数就不会返回新的引用

import {memo, useCallback, useState} from "react";
interface ChildProps{
    onClick:()=>void
}
const Child = memo(({onClick}:ChildProps)=>{
    console.log("child render...")
    return (
        <div onClick={onClick}>child</div>
    )
})


function Parent(){
    const [count, setCount] = useState(0)

    // function handleClick(){
    //     console.log("click")
    // }


    const handleClick = useCallback(()=>{
        console.log("click")
    },[])
    return (
        <div>
            <p>{count}</p>
            <button onClick={e=>setCount(count+1)}>btn</button>
            <Child onClick={handleClick}></Child>
        </div>
    )
}


export default Parent


http://www.kler.cn/a/599837.html

相关文章:

  • OSS Browser2.0安装使用(阿里云对象存储OSS 图形化界面工具2.0版本)
  • <C#> 详细介绍.net 三种依赖注入:AddTransient、AddScoped、AddSingleton 的区别
  • HarmonyOS NEXT(十) :系统集成与调试
  • 【React】List使用QueueAnim动画效果不生效——QueueAnim与函数组件兼容性问题
  • 【Java】Springboot集成itextpdf制作pdf(内附pdf添加表格、背景图、水印,条形码、二维码,页码等功能)
  • WebRTC协议全面教程:原理、应用与优化指南
  • HBuilderX开发微信小程序常见问题及入门教程下载
  • Qt的内存管理机制
  • 2024年认证杯SPSSPRO杯数学建模B题(第二阶段)神经外科手术的定位与导航全过程文档及程序
  • C语言基础08
  • 新版本Springboot的lombok导入依赖出现问题的解决办法
  • Cursor+Claude-3.5生成Android app
  • order by 导致分页出现重复数据问题
  • ### Java二维字符矩阵输入解析:正确读取由0和1组成的矩阵
  • vulkanscenegraph显示倾斜模型(5.4)-相机操纵器
  • 如何查看Unity打包生成的ab文件
  • 23种设计模式-桥接(Bridge)设计模式
  • FPGA_DDS_IP核
  • CS实现票据样式效果
  • 国科云:浅谈DNS在IPv6改造过程中的重要性