首页 专栏 javascript 文章详情 0 如何解决 React.useEffect() 的无限循环 ?...无限循环和副作用更新状态 假设我们有一个功能组件,该组件里面有一个 input 元素,组件是功能是计算 input 更改的次数。...问题在于useEffect()的使用方式: useEffect(() => setCount(count + 1)); 它生成一个无限循环的组件重新渲染。...引用更改本身不会触发组件重新渲染。 ? 2. 无限循环和新对象引用 即使正确设置了useEffect()依赖关系,使用对象作为依赖关系时也要小心。...这是一个无限循环问题。 为什么会这样? secret对象被用作useEffect(..., [secret])。
为什么这里提的是 「可能」 ,下面会进行解释。...还有另外一种场景是,在监听函数中创建新的 ResizeObserver 实例,导致循环的每一次迭代都有新的元素需要通知,那么最终循环就会因为内存溢出而终止,这里不作过多讨论。...如果避免无限循环 无限循环的场景是真实存在的,想要避免无限循环的出现,我们需要给循环过程加上一些限制,以此来解除循环。...有三种限制策略可以考虑: 执行次数限制 允许执行最多次数 N 次循环,当超过次数 N 时,循环终止 优点是实现简单,并且具有一致性,当这个算法在不同的机器上运行时都能有相同的表现 缺点是 N 的定义太过随意...,缺乏比较可靠的结论定义 执行时间限制 循环最多执行 N ms 时长,当超过这个时间时循环终止 虽然听起来实现很简单,但我们无法保证具体会执行多少次调度,在不同性能的机器上,每次执行的时间是不同的,意味着不同的机器执行次数会不同
无限触发的计数器 我们将之前 useState 的例子做个小改动,将点击计数 count 改为渲染次数计数 renderCount。...为什么会这样?...而重渲染又会再次触发 setRenderCount……从而无限循环触发,导致运行的情况与我们想要的效果不太一样。 2....函数式组件本身相当于 render,每次组件重新渲染都会被执行,而 renderCount 作为其中一个普通的局部变量,每次都会被赋值为 0 而非上一次修改的值。...导致不管重新渲染几次,页面上的计数始终为0。
二、问题现状及分析 我们以酒店某一多功能列表为例(下图),设定检测标准(setData次数及该setData的响应时效作为指标),检测情况如下: 指标 setData次数 渲染耗时(ms) 第一次进入列表页...根据上面多次测出的指标值,以及视觉体验上来看,存在以下问题: 2.1 首次进入列表页的加载时间过长,白屏时间久 列表页请求的接口时间过长; 初始化列表也是setData数据量过大,且次数过多; 页面节点数过多...,导致渲染耗时较长; 2.2 页面筛选项的更新卡顿,下拉动画卡顿 筛选项中节点过多,更新时setData数据量大; 筛选项的组件更新会导致页面跟着一起更新; 2.3 无限列表的更新卡顿,滑动过快会白屏...核心的思路是只渲染显示在屏幕的数据,基本实现就是监听 scroll 事件,并且重新计算需要渲染的数据,不需要渲染的数据留一个空的 div 占位元素。...3.6 React.memo 当复杂页面子组件过多时,父组件的渲染会导致子组件跟着渲染,React.memo可以做浅层的比较防止不必要的渲染: const MyComponent = React.memo
# 为什么使用 useRef 在 JavaScript 中,我们可以创建变量并将其赋给不同的值。然而,在函数组件中,每次重新渲染时,所有的局部变量都会被重置。...使用场景: 传递回调函数给子组件:当我们将一个函数作为 prop 传递给子组件,并且该函数的依赖项在父组件重新渲染时可能发生变化时,可以使用 useCallback 缓存该函数,以确保子组件只在依赖项变化时才重渲染...修改状态可能导致无限循环的重新渲染。正确的做法是使用 setState 或提取相关的状态变量,然后在 useEffect 的依赖项数组中引用。...如果回调函数内部又引发了状态的变化,可能导致无限循环的渲染。 解决这个问题的方法是仔细选择依赖项,确保只在需要的时候才触发 useEffect 的回调函数。...循环、添加判断、嵌套函数中禁用 hooks # 官方解释: 不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层以及任何 return 之前调用 Hooks # 为什么呢
因此,这里的应用程序将在每次渲染时执行setCount函数。因此,这会导致一个无限循环: 是什么导致了这个问题?让我们一步一步来分析这个问题: 在第一次渲染时,React会检查count的值。...在这里,由于count为0,程序执行useEffect函数 稍后,useEffect调用setCount方法并更新count的值 之后,React重新呈现UI以显示count的更新值 此外,由于useEffect...它这样做是为了验证依赖项是否已经更新 这里的问题是,在每次呈现期间,React都会重新定义logResult的引用 因此,这将在每个循环中重新触发useEffect函数 因此,React会调用setCount...由于这个参考值是稳定的,React不应该无限地重新渲染UI: const logResult = useCallback(() => { return 2 + 2; }, []); // logResult...和之前一样,React使用浅比较来检查person的参考值是否发生了变化 因为person对象的引用值在每次渲染时都会改变,所以React会重新运行useEffect 因此,在每个更新周期中调用setCount
、更新状态,并导致重新渲染,而且是无限重新渲染。... Count: {counter} ); } 如果你像上面的例子那样使用一个条件,请确保该条件不总是返回一个真值,因为这将导致无限的重新渲染循环...React limits the number of renders to prevent an infinite loop"错误也会在使用useEffect方法时发生,该方法的依赖会导致无限重新渲染。...这意味着该钩子会在每次渲染时运行,它会更新组件的状态,然后无限重新运行。 传递依赖 解决该错误的一种办法是,为useEffect提供空数组作为第二个参数。...该代码将计数器递增到1,并且不再运行,无论App组件是否被重新渲染。 如果你必须指定一个依赖来无限地重新渲染你的组件,试着寻找一个可以防止这种情况的条件。
在编写flush之前,我们先额外讲讲「无限循环」的情况。...结果就是一个无限循环。 所以,我们需要杜绝上面的情况发生,在我们的代码中,我们采用了基于「运行次数限制」的循环退出条件。这样就可以反正无限循环发生。...0; if (count < 100) { // 防止无限循环,限制最大运行次数 effectRunCounts.set(effect, count + 1);...0; if (count < 100) { // 防止无限循环,限制最大运行次数 effectRunCounts.set(effect, count + 1);...验证是否可以杜绝无限执行 const effectLoop = () => { console.count('执行次数') state.a++; } createEffect(effectLoop
刚好最近在的项目中, 遇到了一个长列表的性能问题,试过多种方案, 最后得以解决。 今天就给大家分享一下。...所以,影响渲染性能的元素很可能就是它。 渲染性能 除了组件的问题,还有可能是渲染的问题。 首先,原来无限滚动的逻辑就是基于scroll事件,通过不断滚动触发的回调,重新计算渲染到页面上的区间。...所以要减少渲染成本: 减少自己的父组件渲染成本,React.memo/React.useMemo/React.useCallback. 减少Select渲染成本(比较麻烦,而且效果不明显。...每次多加载一屏的数据,循环如此,直到整个列表都渲染到页面上。 在线demo: https://codesandbox.io/s/gundongjiazai-antd491-forked-vtchw?...下拉懒加载 优点:防止用户快速拖动的出现闪动问题。
React Hooks 的限制主要有两条:不要在循环、条件或嵌套函数中调用 Hook;在 React 的函数组件中调用 Hook。那为什么会有这样的限制呢?...那为什么不要在循环、条件或嵌套函数中调用 Hook 呢?因为 Hooks 的设计是基于数组实现。在调用时按顺序加入数组中,如果使用循环、条件或嵌套函数很有可能导致数组取值错位,执行错误的 Hook。...通过事务处理机制,将多次DOM修改的结果一次性的更新到页面上,从而有效的减少页面渲染的次数,减少修改DOM的重绘重排次数,提高渲染性能。...如果 render() 方法依赖于其他数据,则可以调用 forceUpdate() 强制让组件重新渲染。...Vue. js还具有对于“可变状态”的“ reactivity”的重新渲染的自动化检测系统。
在 React 应用中,我们经常需要处理滚动事件(onScroll),以实现一些与滚动相关的功能,如无限滚动加载、滚动到顶部按钮等。...节流和防抖当滚动事件频繁触发时,节流(throttling)和防抖(debouncing)是常用的技术,用于限制事件处理函数的执行次数。...节流将事件处理函数的执行频率限制在一定的时间间隔内,而防抖则延迟事件处理函数的执行,并在延迟期间取消之前的执行请求。在 React 中,我们可以使用第三方库(如 lodash)来实现节流和防抖功能。...通过使用节流或防抖,我们可以控制滚动事件处理函数的触发频率,避免过多的计算和渲染。虚拟化技术当滚动区域包含大量的元素时,为了避免性能问题,我们可以使用虚拟化技术来优化滚动事件处理。...虚拟化技术只渲染可见区域内的元素,而不是全部渲染。这样可以减少 DOM 操作和计算量,提高滚动的流畅性和响应速度。
React Hook 的使用限制有哪些?React Hooks 的限制主要有两条:不要在循环、条件或嵌套函数中调用 Hook;在 React 的函数组件中调用 Hook。那为什么会有这样的限制呢?...那为什么不要在循环、条件或嵌套函数中调用 Hook 呢?因为 Hooks 的设计是基于数组实现。在调用时按顺序加入数组中,如果使用循环、条件或嵌套函数很有可能导致数组取值错位,执行错误的 Hook。...为什么列表循环渲染的key最好不要用index举例说明变化前数组的值是[1,2,3,4],key就是对应的下标:0,1,2,3变化后数组的值是[4,3,2,1],key对应的下标也是:0,1,2,3那么...经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个UI界面。...哪些方法会触发 React 重新渲染?重新渲染 render 会做些什么?(1)哪些方法会触发 react 重新渲染?
笔者认为,react-hooks思想和初衷,也是把组件,颗粒化,单元化,形成独立的渲染环境,减少渲染次数,优化性能 useCallback useContext useEffect useLayoutEffect...2.为什么要使用hooks 我们为什么要使用react-hooks呢,首先和传统的class声明的有状态有着显著的优点就是 1 react-hooks可以让我们的代码的逻辑性更强,可以抽离公共的方法,公共组件...render函数等) 3 react-hooks可能把庞大的class组件,化整为零成很多小组件,useMemo等方法让组件或者变量制定一个适合自己的独立的渲染空间,一定程度上可以提高性能,减少渲染次数..., memo, 我们知道class声明的组件可以用componentShouldUpdate来限制更新次数,那么memo就是无状态组件的ShouldUpdate , 而我们今天要讲的useMemo就是更为细小的...如果有一个循环的list元素,那么useMemo会是一个不二选择,接下来我们一起探寻一下useMemo的优点。 1 useMemo可以减少不必要的循环,减少不必要的渲染。
渲染(Render)时影响性能的点 React 处理 render 的基本思维模式是每次一有变动就会去重新渲染整个应用。...上文描述的 React 组件渲染机制其实是一种较好的做法,很好地避免了在每一次状态更新之后,需要去手动执行重新渲染的相关操作。...鱼和熊掌不可兼得,带来方便的同时也会存在一些问题,当子组件过多或者组件的层级嵌套过深时,因为反反复复重新渲染状态没有改变的组件,可能会增加渲染时间又会影响用户体验,此时就需要对 React 的 render...shouldComponentUpdate 来决定是否组件是否重新渲染,如果不希望组件重新渲染,返回 false 即可。 在 React 中 PureComponet 的源码为 if (this....推荐阅读 网上都说操作真实 DOM 慢,但测试结果却比 React 更快,为什么?
它会带来很多好处,例如: 零副作用 不可变的数据对象更易于创建,测试,和使用; 利于解耦; 更加利于追踪变化; 在 React 环境中,我们使用 Component 的概念来维护组件内部的状态,对状态的更改可以导致组建的重新渲染...== nextState.users) { return true; } return false; } 即使用户的数组发生了改变,React 也不会重新渲染UI了,因为他们的引用是相同的...译注:函数组件也可以做纯组件的优化:React.memo(…) 是 React v16.6 中引入的新功能。它与 React.PureComponent 类似,它有助于控制 函数组件 的重新渲染。...节流可以通过多种方式实现。您可以限制触发的事件的次数或延迟正在执行的事件来限制程序执行一些昂贵的操作。 防抖 与节流不同,防抖是一种防止事件触发器过于频繁触发的技术。...只要 props 发生变化,这个无状态组件就会重新渲染。
hooks 规则官网 hoos 规则中明确的提出 hooks 不要再循环,条件或嵌套函数中使用。图片为什么不可以?我们来看下下面这样一段代码。...来重新执行 useEffect 内的函数 // 因此这里也就需要记录定时器,当卸载的时候我们去清空定时器,防止多个定时器重新触发 useEffect(() => { const id = setInterval...因为 React render 的时候它会帮我们处理这正是setAge(age => age + 1)做的事情。再重新渲染的时候他会帮我们执行这个方法,并且传入最新的状态。...因此产生了无限循环。...源码,至于重新渲染这块 react-dom 还没有去深入了解。
hooks 为什么不能放在条件判断里以 setState 为例,在 react 内部,每个组件(Fiber)的 hooks 都是以链表的形式存在 memoizeState 属性中图片update 阶段,...只要父组件类型不同,就会被重新渲染。这也就是为什么 shouldComponentUpdate、PureComponent 及 React.memo 可以提高性能的原因。...、哪些方法会触发 React 重新渲染?重新渲染 render 会做些什么?(1)哪些方法会触发 react 重新渲染?...(2)经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;(3)在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异...ref」外,还有一种「防止ref失控的措施」,那就是useImperativeHandle,他的逻辑是这样的:既然「ref失控」是由于「使用了不该被使用的DOM方法」(比如appendChild),那我可以限制
领取专属 10元无门槛券
手把手带您无忧上云