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

memo、useCallback、useMemo的区别和用法

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

1.9K30

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的子元素,

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

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

29630

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.5K20

手写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.6K22

8个console.log的解决方案

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

55020

Hooks的useState

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

1K30

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

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

2.4K21

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.2K21

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

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

4.8K41

深入学习 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函数的节点上。

1K31

闭包

React闭包陷阱 React Hooks是React 16.8引入的一个新特性,其出现让React的函数组件也能够拥有状态和生命周期方法,其优势在于可以让我们不编写类组件的情况下,更细粒度地复用状态逻辑和副作用代码...表达式是可见也都能够被引用,如果一个变量或者其他表达式不在当前的作用域,则将无法使用。...在这里我们需要关注第二种方案如何进行重试,我们发起请求的时候通常会携带比较多的信息,比如url、token、body等数据进行查询,如果我们需要进行重试,那么肯定需要找个地方把这些数据存储下来以备下次发起请求...0,这就是因为我们的useEffect保持了旧的函数作用域,而那个函数作用的count为0,那么打印的值当然就是0,同样的useCallback也会出现类似的问题,解决这个问题的一个简单的办法就是依赖数组中加入...React我们就可以借助useRef来做到这点,通过保持对象的引用来解决上述的问题。 // https://codesandbox.io/s/react-closure-trap-jl9jos?

41420
领券