10函数组件设计模式如何应对复杂条件渲染场景_第1页
10函数组件设计模式如何应对复杂条件渲染场景_第2页
10函数组件设计模式如何应对复杂条件渲染场景_第3页
10函数组件设计模式如何应对复杂条件渲染场景_第4页
10函数组件设计模式如何应对复杂条件渲染场景_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

下载下载2021-06-1712:49《ReactHooks核心原理与实战12:49所谓设计模式,就是针对特定场景,提供一种公认的最佳实践。在前面的课程中,我们已经提到了不少模式,比如保证状态的唯一数据源,语义化的拆分复杂组件,等等。熟练掌握这些模式,可以让我们的代码更加简洁直观。一个和Hooks相关,用于解决Hooks另一个则是经典的renderpropsUI2HooksHooks,而不能放在条件判断、循环等语句中,同时也不能在可能的return语句之后执行。换句话说,Hooks必须按顺序被执行到。这个规则存在的原因就在于,React需要在函数组件内部维护所用到的Hooks的状态,所以我们无法在条件语句中使用Hooks,这因而会给我们实现业务逻辑带来一定的局限。visiblevisiblevisibletrueimportimport{Modal}from"antd";importuseUserfrom"../09/useUser";functionUserInfoModal({visible,userId,...rest})//当visible为falseif(!visible)return//这一行Hook在可能的returnconst{data,loading,error}=return<Modalvisible={visible}{/*对话框的内容nullreturnuseUserHook。所以在你的编辑器配置了ReactHooks的ESLint插件之后,会给出下面的错误提示:可以看到,因为Hooks使用规则的存在,使得有时某些逻辑无法直观地实现。换句话说,Hooks具体做法就是把条件判断的结果放到两个组件之中,确保真正renderUI的组件收到的所针对刚才我们讲的例子,就可以在UserInfoModal外层加一个容器,这样就能实现条件渲////定义一个容器组件用于封装真正的UserInfoModalexportdefaultfunctionUserInfoModalWrapper({...rest,//使用rest获取除了visible5})//如果对话框不显示,则不renderif(!visible)return//return<UserInfoModalvisible{...rest}10这样的话,我们就间接实现了按条件去执行Hooks的逻辑。在实际的使用场景中,可能判断条件不止visible一个属性,而会是一些属性的组合,来具体决定render什么内容。虽然这样的做法不够直观,但其实也能带来一些好处。比如说,在容器模式中我们其实也可以看到,条件的隔离对象是多个子组件,这就意味着它通常用于一些比较大块逻辑的隔离。所以对于一些比较细节的控制,其实还有一种做法,就是把判断条件放到Hoks中去。比如上节课的例子,我们需要先发送请求,获得文章信息,从而知道作者的ID是什么,这样才能用useUser这个Hook去获取用户数据。constconstArticleView=({id})=>const{data:article,loading}=useArticle(id);letuser=null;if(article?.userId)user=//6可以看到,我们需要的article这个对象获取到之后,才能去用useUser这个Hook再去获取用户信息。那么同样的,既然Hook不能放到条件语句中,那我们应该如何做呢?事实上,上一讲的例子已经给出了答案,那就是把条件语句自包含在Hook之中。这样当没有传递userId给useUser这个Hook的时候,副作用里实际上什么也不做,比如:functionfunctionuseUser(id)const[data,setData]=const[loading,setLoading]=useState(false);const[error,setError]=useState(null);useEffect(()=>{//当idif(!id)// 10useEffectID话,这个Hook就可以在组件中无条件使用了。总体来说,通过这样一个容器模式,我们把原来需要条件运行的Hoos拆分成子组件,然后通过一个容器组件来进行实际的条件判断,从而渲染不同的组件,实现按条件渲染的目的。这在一些复杂的场景之下,也能达到拆分复杂度,让每个组件更加精简的目的。使用renderpropsUI对于Reactrenderprops。因为它解决了UIClass义,renderpropsrender这个函数从而render实际的内容。ClassrenderpropsHOC(高阶组件)的两把利器,但是实际上,HOC的所有场景几乎都可以用renderprops不过在如今的函数组件情况下,Hooks有一个局限,那就是只能用作数据逻辑的重用,而一旦涉及UI表现逻辑的重用,就有些力不从心了,而这正是renderprops擅长的地方。所以,即使有了Hooks,我们也要掌握renderprops这个设计模式的用法。为了方便你理解enerros这个模式,我先给你举一个数据逻辑重用的简单例子。这个例子仍然是我们熟悉的计数器。有两个按钮,加一和减一,并将当前值显示在界面上。执行的效果如下图所示:如果不考虑UIcountincrease1decrease:让数值减1renderprops的组件自行决定UI如何展现。下面的代码就是这个计数器的renderprops的实现: setCount(count+ },constdecrement=useCallback(()=>setCount(count- },13

returnchildren({count,increment,decrementrenderUIfunctionfunctionCounterRenderPropsExample(){return({({count,increment,decrement})=>return<buttononClick={decrement}>-<button 15childrentagtag会作为children属性传递给组件。那么在使用的时候,是直接传递了一个函数过去,由实现计数逻辑的组件去调用这个函数,并把相关的三个参数count,increase和decreaseUI。那么在这种场景下,其实用Hooks是更方便的,在第6讲中,我其实已经给过这么计数器的Hooks实现的例子,代码如下:importimport{useState,useCallback}fromfunctionuseCounter()//定义count这个stateconst[count,setCount]=//实现加1constincrement=useCallback(()=>setCount(count+1),//实现减1constdecrement=useCallback(()=>setCount(count-1),//将业务逻辑的操作exportreturn{count,increment,decrement很显然,使用Hooks的方式是更简洁的。这也是为什么我们经常说Hooks能够替代renderprops这个设计模式。但是,需要注意的是,Hooks仅能替代纯数据逻辑的renderpropsUIrenderprops的逻辑,这就是我一再强调必须要掌握renderprops这种设计模式的原因。为了解释这个用法,我给你举一个例子。比如,我们需要显示一个列表,如果超过一定数量,则把多余的部分折叠起来,通过一个弹出框去显示。下面这张图可以比较直观地展示这个需求的实际运行效果:可以看到,这里展示了两个列表。一个只显示用户名,这在一些社交软件的界面上很常见,只显示几个点赞的用户,多余的用一个数字来表示,鼠标移上去则跳转或者显示完整列表。5UIHooks通过renderprops这个设计模式。renderprops的ListWithMoreimportimport{Popover}fromfunctionListWithMore({renderItem,data=[],max})constelements=data.map((item,index)=>renderItem(item,index,data));constshow=elements.slice(0,max);consthide=return<spanclassName="exp-10-list-with-{hide.length>0&&<Popovercontent={<divstyle={{maxWidth:500<spanclassName="more-items-and{"<spanclassName="more-items-trigger">{hide.length} 112importdatafrom3functionListWithMoreExample()=>return<divclassName="exp-10-list-with-7<h1>User8<divclassName="user-9Likedby:{"renderItem={(user)=>return<spanclassName="user-<br<br<h1>User<divclassName="user-<divclassName="user-list-rowuser-list-row-<spanclassName="user-name-<span>JobrenderItem={(user)=>return<divclassName="user-list-<spanclassName="user-name-43可以看到,代码里使用了两个ListWithMore组件,通过renderItem这个属性,我们可以自主决定该如何渲染每一个列表项,从而把一部分UI逻辑抽象出来,形成一个可复用的逻HooksrenderpropsHooks hooks-course-20vzg。你可以fork后自己动手尝试。renderprops分享给需要的人,Ta订阅后你可得20赞9 提建©上一 下一 Free

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论