2024年9月hooks中的生命周期(hooks中的设计模式)
⑴hooks中的生命周期(hooks中的设计模式)
⑵本文主要介绍钩子中的生命周期(钩子中的设计模式),下面一起看看钩子中的生命周期(钩子中的设计模式)相关资讯。
⑶钩子中useStateReact的数据从上到下单向流动,即从父组件到子组件,组件的数据存储在props和state中。其实在任何应用中,数据都是必不可少的。我们需要直接改变页面的区域来刷新视图,或者间接改变其他地方的数据。在React中,我们使用道具和状态来存储数据。状态的主要功能是保存、控制和修改自身的变量状态。状态是在组件内部初始化的,可以由组件自己修改,但是它可以不要在外面接触或修改。可以认为它是一个只能由组件本身控制的本地数据源。对于反应式函数组件,useState用于管理自己的状态挂钩函数。
⑷钩子#关于钩子的含义,阮一峰解释说,钩子的含义是,组件尽量写成纯函数,如果需要外部函数和副作用,就用钩子把外部代码钩进去,钩子就是那些钩子。我觉得这个解释非常到位。以useState为例。在编写一个函数组件时,这个函数被挂接并使用,一些内部作用域变量,也称为闭包,存储在这个函数内部,所以挂接也可以理解为挂接另一个作用域变量和函数逻辑,在当前作用域中使用。至于为什么要用React钩子,综上,还是为了组件复用,尤其是更细粒度的组件复用。React中代码重用的解决方案层出不穷,但总体来说,代码重用仍然非常复杂,这很大程度上是因为细粒度的代码重用不应该与组件重用在一起。基于组件的解决方案如HOC、RenderProps等,相当于先把要复用的逻辑打包成组件,再利用组件复用机制实现逻辑复用,自然受到组件复用的限制。因此存在扩展性受限、ref划分、包装器Hell等问题。,所以我们需要有一个简单直接的代码复用方法,函数。将可复用的逻辑分离成功能应该是最直接、成本最低的代码复用方法,但是对于状态逻辑,还是需要一些抽象模式(比如可观察)来实现复用。这就是Hooks的思想,将函数视为最小的代码复用单元,构建一些模式来简化状态逻辑的复用。与上面提到的其他方案相比,Hooks使得组件中的逻辑复用不再与组件复用在一起,真正是在尝试从底层解决(组件之间的)细粒度逻辑。此外,这种声明性逻辑重用方案进一步将组件之间的显式数据流和组合的思想扩展到了组件。
⑸官方对使用react钩子的动机解释如下:钩子解决了过去五年我们在编写和维护react时遇到的各种看似无关的问题。无论你是否在学习React,你每天都在使用它,甚至你只是在使用一些组件模型相似的框架来进行React。你或多或少会注意到这些问题。跨组件重用带状态的有状态逻辑非常困难。:React没有提供将复用行为绑定到组件的方法,比如connectittostore,一个类似redux的状态管理库。如果你使用过React一段时间,你可能会熟悉渲染道具、高阶高阶组件等模式来尝试解决这些问题,但这些模式需要你在使用时重构组件,可能会比较麻烦,而且会使代码不可持续。使用钩子,您可以从组件中提取有状态逻辑,这样您就可以独立地、重复地使用它们。如果你在ReactDevTools中看到一个典型的React应用,你可能会发现一个由提供者、消费者、高阶组件、渲染道具和其他抽象层组成的包装器地狱。虽然我们可以在DevTools中过滤它们,但这反映了一个更深层次的问题:React需要一个更好的原生方法来共享有状态逻辑。使用钩子,可以从组件中抽象出包含状态的逻辑,便于独立测试和重用。同时,钩子允许您在不改变组件结构的情况下重用有状态逻辑,因此您可以很容易地在许多组件之间或与社区共享钩子。复杂的组件变得难以理解。:,我们经常要维护一个简单但难以管理的状态逻辑,它包含了混沌状态逻辑和一堆有副作用的组件。随着开发的深入,它们会越来越大,越来越乱,各种逻辑散落在组件的各处,每个生命周期钩子都包含一堆不相关的逻辑。例如,我们的组件可能在ponentdimount和ponentDidUpdate中执行一些数据拉取工作,但是同一个ponentdimount方法也可能包含一些none。关闭逻辑,比如设置事件(稍后需要在pon测试来说也非常困难,这也是很多人喜欢结合React和状态管理库的原因之一,但这通常会引入太多的抽象,需要你在不同的文件之间跳转,并且增加了重用组件的难度。Hooks允许你根据相关部分(比如设置订阅或者获取数据)将一个组件拆分成更小的功能,而不是基于生命周期的方法强制拆分。您还可以选择使用reducer来管理组件的本地状态,使其更具可预测性。难以理解的Class:,在代码复用和代码管理上会遇到困难。我们也发现课堂是学习反应的一大障碍。你必须了解JavaScript中这个的工作模式,它和其他语言有很大的不同。一定不要忘记绑定事件处理程序,也没有稳定的语法建议。这些代码非常多余。你可以很好地理解道具、状态和自顶向下的数据流,但是你可以不要对班级做任何事情。即使是有经验的React开发者,功能组件和类组件也是有区别的,甚至两个组件的使用场景也要区分。另外,React已经发布五年了,我们希望它在未来五年也能与时俱进,就像其他库如Svelte、Angular和Glimmer所展示的那样。最近,我们一直在使用Prepack进行组件折叠实验,并取得了初步成果。但是我们发现,使用类组件会在不经意间鼓励开发者使用一些让优化措施失效的方案,类也给当前的工具带来了一些问题。例如,类可以不能很好的压缩,会使热过载不稳定。因此,我们希望提供一个API,使代码更容易优化。为了解决这些问题,Hook允许你在非类的情况下使用更多的React特性。从概念上讲,React组件一直更像一个函数,而Hook在不牺牲React精神原则的情况下拥抱了函数。Hook提供了无需学习复杂字母的问题解决方案。数字或响应编程技术。
⑹Us-dust-kbdi?.file=/src/app.tsx.
⑺从"反应"进口与贸易。/styles.CSS"导出默认函数App{const[count,setcount]=usestate();console.log("刷新");constaddcount==setcount(count);return(div{Count}/divbuttononClick={addCount}Count/button/);}第一次渲染页面时,会渲染App/function组件,实际上是调用App方法获取一个虚拟的DOM元素,渲染到浏览器页面。当用户点击按钮按钮时,它会调用addCount方法,然后再次渲染App/function组件,这实际上是调用App方法来获得一个新的虚拟DOM元素,然后React会执行DOMdiff算法,这个算改变它。换句话说,其实每次setCount都会重新执行App函数,通过console.log("刷新"),每次点击按钮控制台都会打印刷新。那么问题来了。第一次渲染页面,执行次操作时,将调用App函数执行const[count,setcount]=usestate()。这一行代码,那么它是如何在运算后执行同样的代码,却不初始化变量n,也就是始终为,而是得到n的最新值,考虑到上面的问题,我们可以简单的实现一个useMyState函数。关于钩子为什么叫钩子的问题,我们提到了可以挂接一个函数作用域。然后我们可以完全实现一个钩子来钩住一个作用域。简单来说就是在useMyState中保存一个变量,也就是在闭包中保存这个变量。然后这个变量保存最后一个值,再次调用时,只需拿出之前保存的值,。ox.io/s/fancy-dust-kbdi?文件=/src/use-my-state-version-.
⑻从"react-DOM"从导入应用程序"。/App"将其转换并导出以便我们可以强制刷新`app/`exportconstforcerefresh=={console.log("forcefreshapp/");constrootelement=document.getelementbyid("根与树);render(App/,rootelement);};force刷新;copy//us:any=null;导出函数us:T):[T,(n:T)=void]{sav:T=保存状态;consts:T):void={saveState=newstate;force刷新;};return[rtnState,setState];}从"。/use-my-state-version-进口与贸易。/styles.CSS"导出默认函数App{const[count,setcount]=useMyState();console.log("刷新");constaddcount==setcount(count);返回(div{Count}/divbuttononClick={addCount}Count/button/);}在cod:做成对象,比如sav:,m:},不符合要求,因为使用us:[,]。事实上,在React中,数组被替换为类似于单个链表的形式。通过n-dust-kbdi?.file=/src/use-my-state-version-.ts.
⑼从"react-DOM"从导入应用程序"。/App"将其转换并导出以便我们可以强制刷新`app/`exportconstforcerefresh=={console.log("forcefreshapp/");constrootelement=document.getelementbyid("根与树);render(App/,rootelement);};force刷新;copy//us:任意[]=[];设ind:数=;导出函数使用我的状态tat:T):[T,(n:T)=void]{constcurIndex=index;指数;saveState[curIndex]=saveState[curIndex]||state;constrtnStat:T=saveState[curIndex];consts:T):void={saveState[curIndex]=newstate;索引=;//您必须在渲染前后将“index”的值重置为“”,否则您可以t确定`挂钩借助调用序列来forcerefresh;};return[rtnState,setState];}从"。/use-my-state-version-进口与贸易。/styles.CSS"导出默认函数App{const[count,setcount]=useMyState();const[count,setcount]=useMyState();console.log("刷新");constaddcount==setcount(count);constaddcount==setcount(count);return(div{count}/divbuttononClick={addcount}count/buttondiv{count}/divbuttononClick={addcount}count/button/);}由此可见,多状态下可以实现独立的状态更新,那么问题又来了。app/用的是saveState和index,那么其他组件是什么,就是如果多个组件解决了每个组件的独立作用域,方案每个组件创建一个saveState和index。但是,一个文件中的几个组件会导致保存状态和索引。方案放在组件对应的虚拟节点对象上,这也是React采用的方案。saveState和index变量放在组件对应的虚拟节点对象上,saveState在React中的具体实现称为memoizedState。事实上,在React中,数组被替换为类似于单链表的形式,所有的hook都被next串联起来。可以看出,useState对定义的顺序有很强的依赖性,保存在useState数组中的顺序非常重要。在执行函数组件时,可以通过增加下标来获得相应的状态值,这将迫使你不改变useState的顺序。比如用条件来判断是否执行useState,会导致按顺序得到的值和期望值不一样。这个问题在React.useState本身也会出现,所以React不允许你使用条件判断来控制函数组件中使用状态的顺序,这样会导致得到的值混乱,类似下面的代码,会抛出异常。
⑽copyconstApp=={letstate;if(true){[state,setState]=react.usestate();}return(div{state}/div)}!-ReactHook"使用状态"被有条件地调用。React钩子必须在每个组件renderreact-Hooks/Rules-of-Hooks中以完全相同的顺序被调用。;这只是useState的一个简单实现。React的真实实现可以参考packages/React-reconciler/SRC/Reactfiberhooks.js,React的当前版本是..,也可以简单看一下相关类型。
⑾复制类型hooks={m:any,//指向当前渲染节点的最终状态值Fib:any,//初始化n:更新ANY|NULL,//每次更新后,会给当前需要更新的‘Update’分配最后一个‘Update’,方便react回溯qu:更新QU:钩子|null。//`link;到下一个&";钩子并连接所有的`钩通过&;下一个}一天一个问题。#Copy#Copyjuejin./post/juejin./post/juejin./post/echo