首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

memo、useCallback、useMemo的区别和用法

react在渲染父子嵌套组件的时候,有时会发生不必要的渲染,根据经验总结出来,大致有四种情况需要处理: 父子组件嵌套,父组件未向子组件传值 父子组件嵌套,父组件向子组件传值,值类型为值类型 父子组件嵌套...name 属性和 onClick 属性,此时点击父组件的按钮,可以看到控制台中打印出子组件被渲染的信息。...下面例子中,父组件在调用子组件时传递 info 属性,info 的值是个对象字面量,点击父组件按钮时,发现控制台打印出子组件被渲染的信息。...useMemo 有两个参数: 第一个参数是个函数,返回的对象指向同一个引用,不会创建新对象; 第二个参数是个数组,只有数组中的变量改变时,第一个参数的函数才会返回一个新的对象。...点击次数:{count} ); } 再次点击父组件按钮,控制台中不再打印子组件被渲染的信息了

2K30

ReactPortals传送门

预定义的HTML挂载点: 使用React Portal时,我们需要提前定义一个HTML DOM元素作为Portal组件的挂载。...a,符合预期,接下来鼠标移动到b元素上,控制台打印b,同样符合预期,那么接下来将鼠标移动到c,神奇的事情来了,我们会发现会先打印b再打印c,而不是仅仅打印了c,由此我们可以得到虽然看起来DOM结构不一样了...,但是在React树中合成事件依然保持着嵌套结构,C组件作为B组件的子元素,在事件捕获时依然会从B -> C触发MouseEnter事件,基于此我们可以实现非常有意思的一件事情,多级嵌套的弹出层。...-- ... --> 从树形结构中我们可以看出来,虽然在DOM结构中我们现实出来是平铺的结构,但是在React的事件树中却依旧保持着嵌套结构,那么我们就很容易解答最开始的一个问题...,为什么我们可以无限层级地嵌套,而且当多级弹出层组件的最后一级鼠标移出之后,所有的弹出层都会被关闭,就是因为实际上即使我们的鼠标在最后一级,但是在React树结构中其依旧是属于所有portal的子元素,

26750
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    useMemo依赖没变,回调还会反复执行?

    经常使用React的同学都知道,有些hook被设计为:「依赖项数组 + 回调」的形式,比如: useEffect useMemo 通常来说,当「依赖项数组」中某些值变化后,回调会重新执行。...我们知道,React的写法十分灵活,那么有没有可能,在「依赖项数组」不变的情况下,回调依然重新执行? 本文就来探讨一个这样的场景。...描述下Demo 在这个示例中,存在两个文件: App.tsx Lazy.tsx 在App.tsx中,会通过React.lazy的形式懒加载Lazy.tsx导出的组件: // App.tsx import...应用渲染的结果如下: 现在问题来了,如果我们在useMemo回调中打印个log,记录下执行情况,那么log会打印多少次?...但是内层的React.lazy与外层的React.lazy是不一样的,外层的React.lazy是在模块中定义的: // App.tsx const LazyCpn = lazy(() => import

    39730

    Next.js + TypeScript 搭建一个简易的博客系统

    做个试验,我们在组件里写一句 console.log('aaa')。 结果 Node 控制台、Chrome 控制台都会打印出 aaa。 注意差异 但并不是所有的代码都会运行在两端。...但实际开发中我们需要请求 /user、 /shops 等 API,它们返回的内容是 JSON 格式的字符串。在 Next.js 中怎么实现呢? 使用 Next.js 的 API 模式。...然后我们借助 gray-matter 从 md 文件中解析数据。 lib/posts.tsx 这个文件导出 JSON 数据。...缺点 但这种方式会造成两个问题。一是白屏,目前解决方法是在 AJAX 得到相应之前,页面中先加入 Loading。...因为数据本来不在页面上,通过 ajax 请求后渲染到页面上。 文章列表都是前端渲染的,我们称之为客户端渲染。

    3.9K20

    手写useState与useEffect

    也就是说,实际上每次setCount都会重新执行这个App()函数,这个可以通过console.log("refresh")那一行看到效果,每次点击按钮控制台都会打印refresh。...实际上React中是通过类似单链表的形式来代替数组的,通过next按顺序串联所有的hook,使用数组也是一种类似的操作,因为两者都依赖于定义Hooks的顺序,https://codesandbox.io...解决办法2放在组件对应的虚拟节点对象上,React采用的也是这种方案,将saveState和index变量放在组件对应的虚拟节点对象FiberNode上,在React中具体实现saveState叫做memoizedState...,实际上React中是通过类似单链表的形式来代替数组的,通过next按顺序串联所有的hook。...的顺序,例如使用条件判断是否执行useState这样会导致按顺序获取到的值与预期的值不同,这个问题也出现在了React.useState自己身上,因此React是不允许你使用条件判断去控制函数组件中的useState

    2K10

    干货 | React Hook的实现原理和最佳实践

    不出意外当我们点击页面上的按钮时候,按钮中数字并不会改变;看控制台中每次点击都会输出0,说明useState是执行了。...这里我们就知道了为啥官方文档介绍:不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。...因为我们是根据调用hook的顺序依次将值存入数组中,如果在判断逻辑循环嵌套中,就有可能导致更新时不能获取到对应的值,从而导致取值混乱。...3.2 如何通过React Hook进行数据请求 前端页面免不了要和数据打交道,在Class组件中我们通常都是在componentDidMount生命周期中发起数据请求,然而我们使用Hook时该如何发送请求呢...[...watch]:[] // 判断是否有需要监测的属性 ); return { data } } 点击查看Demo,我们现在点击页面上的按钮发现页面的数据户一直发生变化,控制台也会打印

    10.8K22

    8个console.log的解决方案

    但实际上,控制台对象中也有一些很棒的方法,它们可以帮助我们在控制台中打印出更清晰漂亮的消息。 在今天的文章中,我就来分享一些有关控制台的高级技巧,我们现在开发吧。...另一个有趣的事情是,我们可以在控制台中输出图像,我们只需要设置 background-img 属性。...() 在调试深度嵌套的函数时,我们可能还想输出代码的堆栈跟踪。...React 或 Vue 中渲染或更新的次数时,我们也可以使用 console.count,所以你不需要自己实现一个计数器。...console.assert() 使用 console.assert(),我们可以决定只在条件为假时记录一些内容,并通过避免不必要的消息打印来节省一些控制台空间: console.group() 我们可以使用嵌套组通过视觉关联相关消息来帮助组织您的输出

    62720

    Hooks中的useState

    Hooks中的useState React的数据是自顶向下单向流动的,即从父组件到子组件中,组件的数据存储在props和state中,实际上在任何应用中,数据都是必不可少的,我们需要直接的改变页面上一块的区域来使得视图的刷新...,或者间接地改变其他地方的数据,在React中就使用props和state两个属性存储数据。...state的主要作用是用于组件保存、控制、修改自己的可变状态,state在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改,可以认为state是一个局部的、只能被组件自身控制的数据源,而对于...消费者,higher-order高阶组件,render props和其他抽象层的组件组成的包装器地狱,虽然我们可以在DevTools中过滤它们,但这反应出一个更深层次的问题:React需要一个更好的原生方法来共享...的顺序,例如使用条件判断是否执行useState这样会导致按顺序获取到的值与预期的值不同,这个问题也出现在了React.useState自己身上,因此React是不允许你使用条件判断去控制函数组件中的useState

    1.1K30

    「React TS3专题」亲自动手创建一个类组件(class component)

    content: string; } 2、接着将接口类型在类组件实现 通过添加到类的实现中,实现代码如下: class Confirm extends React.Component数据类型,可以灵活进行定义。 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。...组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。...文件 由于我们修改了 Confirm.tsx 文件,让属性接受动态传值,我们需要在 App.tsx 文件中定义属性内容,示例代码如下: <Confirm title="React and TypeScript...App.tsx 文件中的 Confirm 组件调用中添加新属性,我们来保存 Confirm.tsx 文件,浏览器的效果如下: 没有报错,能正常运行,由于没有给按钮默认文字参数定义值,我们的按钮很难看,

    2.5K21

    如何使用 React、TypeScript、TailwindCSS 和 Vite 创建 Chrome 插件

    将 React 与 Vite 集成 在 Vite 中设置 React 创建 Vite 项目后,导航到项目目录并运行 npm install。...创建第一个组件 在 src 文件夹中创建一个新组件,例如 Popup.tsx: import React from "react"; const Popup: React.FC = () => (...{js,ts,jsx,tsx}"], theme: { extend: {}, }, plugins: [], }; 然后,通过在 src/index.css 中添加以下行来包含 Tailwind...该弹出窗口的内容来自 App.tsx 组件中的 Popup.tsx 组件。 要测试你的扩展,打开 Chrome 并导航到 chrome://extensions。...调试技巧 如果某些东西不起作用,请检查控制台中的错误。你可以通过右键点击扩展弹出窗口并选择 检查 来访问控制台。 发布你的扩展 准备提交 在发布之前,确保你的扩展符合 Chrome 网上应用店的政策。

    41810

    ahooks 是怎么解决 React 的闭包问题的?

    ) => setCount((val) => val + 1)}>增加 1 ); }; 代码示例[4] 当我点击按钮的时候,发现 setInterval 中打印出来的值并没有发生变化...在组件更新的过程中,hooks 函数执行的顺序是不变的,就可以根据这个链表拿到当前 hooks 对应的 Hook 对象,函数式组件就是这样拥有了state的能力。...中。从而保证能够正确拿到相应 hook 的 state。 useEffect 接收了两个参数,一个回调函数和一个数组。...但是之前的回调函数还是在的,它还是会每隔 1s 执行 console.log("setInterval:", count);,但这里的 count 是之前第一次执行时候的 count 值,因为在定时器的回调函数里面被引用了...file=/App.tsx [6]从react hooks“闭包陷阱”切入,浅谈react hooks: https://juejin.cn/post/6844904193044512782 [7]React

    1.3K21

    深入学习 React 合成事件

    click ); } 上面的代码运行后,会在控制台中分别打印出...file=/src/App.tsx:0-1109 ? 首先点击第一个按钮,发现有两个update被打印出,意味着被render了两次。 ? 点击第二个按钮,只有一个update被打印出来。...file=/src/App.tsx:519-749 ? 首先点击第一个按钮,只有一个update被打印出来。 ? 点击第二个按钮,还是只有一个update被打印出来。...React17中的事件改进 在最近发布的React17版本中,对事件系统了一些改动,和16版本里面的实现有了一些区别,我们就来了解一下17中更新的点。...(),但还是会导致另外一个React版本上绑定的事件没有被阻止触发,所以在17版本中会把事件绑定到render函数的节点上。

    1.1K31

    「React进阶」react-router v6 通关指南

    整体架构设计 路由状态传递 至于在 React 应用中,路由状态是通过什么传递的呢,我们都知道,在 React 应用中, Context 是一个非常不错的状态传递方案,那么在 Router 中也是通过...因为在新的架构中 ,Routes 充当了很重要的角色,在 react-router路由原理 文章中,曾介绍到 Switch 可以根据当前的路由 path ,匹配唯一的 Route 组件加以渲染。...新版本的路由可以说把路由从业务组件中解耦出来,路由的配置不在需要制定的业务组件内部,而是通过外层路由结构树统一处理。...我们打印 matches 看一下数据结构。 11.jpg 还有一点就是 useRoutes 内部用了 useLocation。...使用层面上: 老版本路由,对于嵌套路由,配置二级路由,需要写在具体的业务组件中。

    5.5K41
    领券