文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

React中memo、useCallback和useMemo的使用场景是什么

2023-07-05 08:51

关注

这篇“React中memo、useCallback和useMemo的使用场景是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“React中memo、useCallback和useMemo的使用场景是什么”文章吧。

memo()、useCallback()、useMemo()使用场景

当父组件的props或state变化时,render重新渲染,但传递给子组件的props没有发生变化说着只是简单调用了一下子组件,这时子组件也要重新渲染,这就导致了组件的不必要的渲染

React.memo()

当父组件只是简单调用子组件,并未给子组件传递任何属性,我们可以通过memo来控制函数组件的渲染

React.memo()将组件作为函数(memo)的参数,函数的返回值(Child)是一个新的组件。

import { useState } from "react";import { Child } from "./child";export const Parent = () => {  const [count, setCount] = useState(0);  const increment = () => setCount(count + 1);  return (    <div>      <button onClick={increment}>点击次数:{count}</button>      <Child />    </div>  );};
import {memo} from 'react'export const Child=memo(()=>{    consloe.log('渲染了')    return <div>子组件</div>})//使用memo()包裹后的组件,在Parent组件重新渲染更新时,Child组件并没有重新渲染更新

当我们传值给子组件时,这时使用memo函数就对控制组件的更新不起作用了

父组件

import { useState } from "react";import { Child } from "./child";export const Parent = () => {  const [count, setCount] = useState(0);  const [name, setName] = useState("小明");  const increment = () => setCount(count + 1);  const onClick = (name: string) => {    setName(name);  };  return (    <div>      <button onClick={increment}>点击次数:{count}</button>      <Child name={name} onClick={onClick} />    </div>  );};

子组件

import { memo } from "react";export const Child = memo(  (props: { name: string; onClick: (value: any) => void }) => {    const { name, onClick } = props;    console.log("渲染了", name, onClick);    return (      <>        <div>子组件</div>        <button onClick={() => onClick("小红")}>改变 name 值</button>      </>    );  });

出现这样结果的原因:

点击父组件按钮时,改变了父组件的count,导致父组件重新渲染

父组件重新渲染时,重新创建了onClick函数,导致传递给子组件的onClick属性发生了变化,导致子组件重新渲染

如果传递给子组件的只有基本数据类型将不会重新渲染

注意: 如果直接使用useState解构的setName传给子组件, 子组件将不会重复渲染,因为解构出来的是一个memoized 函数。

React.useCallback()

所以,在这种情况下我们使用React.useCallback() useCallback(fn, deps)

import { useCallback, useState } from "react";import { Child } from "./child";export const Parent = () => {  const [count, setCount] = useState(0);  const [name, setName] = useState("小明");  const increment = () => setCount(count + 1);//使用useCallback钩子包裹的回调函数是memoized函数,他初次调用该函数时,缓存参数和计算结果,再次调用这个函数时,如果第二个参数依赖项没有发生改变,则直接返回缓存结果,不会重新渲染  const onClick = useCallback((name: string) => {    setName(name);  }, []);  return (    <div>      <button onClick={increment}>点击次数:{count}</button>      <Child name={name} onClick={onClick} />    </div>  );};

但当我们传递的属性name不字符串,而是对象时

父组件

import { useCallback, useState } from "react";import { Child } from "./child";export const Parent = () => {  const [count, setCount] = useState(0);  // const [userInfo, setUserInfo] = useState({ name: "小明", age: 18 });  const increment = () => setCount(count + 1);  const userInfo = { name: "小明", age: 18 };  return (    <div>      <button onClick={increment}>点击次数:{count}</button>      <Child userInfo={userInfo} />    </div>  );};

子组件

import { memo } from "react";export const Child = memo(  (props: { userInfo: { name: string; age: number } }) => {    const { userInfo } = props;    console.log("渲染了", userInfo);    return (      <>        <div>名字: {userInfo.name}</div>        <div>年龄:{userInfo.age}</div>      </>    );  });

点击父组件count,看到子组件每次都重新渲染了。 分析原因跟调用函数是一样的:

这时我们使用 React.useMemo() useMemo(() => fn, dep)

React.useMemo()

useMemo()返回的是一个 memoized 值。

如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值。

import { useMemo, useState } from "react";import { Child } from "./child";export const Parent = () => {  const [count, setCount] = useState(0);  // const [userInfo, setUserInfo] = useState({ name: "小明", age: 18 });  const increment = () => setCount(count + 1);  const userInfo = useMemo(() => ({ name: "小明", age: 18 }), []);  return (    <div>      <button onClick={increment}>点击次数:{count}</button>      <Child userInfo={userInfo} />    </div>  );};

对比useCallback() 和useMemo()

useCallback(fn, deps) 返回该回调函数的memoized回调函数

const onClick = useCallback((name: string) => {   setName(name); }, []);

useMemo(() => fn, dep) 返回的是一个 memoized 值。

const userInfo = useMemo(() => ({ name: "小明", age: 18 }), []);

以上就是关于“React中memo、useCallback和useMemo的使用场景是什么”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯