当前位置: 首页 > Web前端 > HTML

React中元素和组件的区别

时间:2023-03-28 14:53:44 HTML

从问题出发,被问到这样一个问题:我想实现一个useTitle方法。具体使用示例如下:functionHeader(){const[Title,changeTitle]=useTitle();return(changeTitle('newtitle')}></div>)}但是在编写useTitle代码时出了点问题:functionTitleComponent({title}){return<div>{title}</div>}functionuseTitle(){const[title,changeTitle]=useState('默认标题');constElement=React.createElement(TitleComponent,{title});return[Element.type,changeTitle];}这段代码直接报错,连渲染都渲染不出来。如果是你,你会如何修改这段代码?元素和组件其实这是一个很典型的问题,如何区分和使用元素和组件。元素我们先看看React官方文档中对React元素的介绍:Babel会把JSX翻译成一个叫做React.createElement()的函数调用。下面两个示例代码是完全等价的:constelement=<h1className="greeting">Hello,world!</h1>;constelement=React.createElement('h1',{className:'greeting'},'Hello,world!');React.createElement()会预先进行一些检查以帮助您编写无错误的代码,但它实际上会创建一个objectlikethis://注意:这是一个简化的structconstelement={type:'h1',props:{className:'greeting',children:'Hello,world!'}};这些对象称为“React元素”。它们描述了您想在屏幕上看到的内容。你看,React元素其实就是指我们每天写的JSX代码。它会被Babel转换成一个函数调用,最终的结果是一个描述DOM结构的对象。它的数据结构本质上是一个JS对象。在JSX中,我们可以嵌入表达式,例如:constname='JoshPerez';constelement=<h1>你好,{name}</h1>;所以如果我们想使用React元素,那么我们应该这样使用Embedded表达式:constname=<span>JoshPerez</span>;constelement=<h1>你好,{name}</h1>;component组件呢?组件有两种类型,函数组件和类组件://函数组件functionWelcome(props){return<h1>Hello,{props.name}</h1>;}//类组件classWelcomeextendsReact.Component{render(){return<h1>你好,{this.props.name}</h1>;那么如何使用组件呢?constelement=<Welcomename="Sara"/>;对于组件,我们需要用类似于HTML标签的方式来调用它们,Babel会将它们翻译成函数调用constelement=React.createElement(Welcome,{name:"Sara"});所以你看,组件的数据结构本质上就是一个函数或者类。当你用元素标签调用它时,函数或类将被执行并最终返回一个React元素。如何解决问题虽然这些内容都来自于React官方文档,但是如果你能清楚的理解React元素和组件的区别,那么一开始就已经可以解决问题了。至少有两种方法可以解决,一种是返回React元素,另一种是返回React组件。我们返回React元素的第一种方式:constroot=ReactDOM.createRoot(document.getElementById('root'));functionHeader(){const[Title,changeTitle]=useTitle();//在这里,因为它返回一个React元素,所以我们使用{}嵌入表达式return(<divonClick={()=>changeTitle('newtitle')}>{Title}</div>)}functionTitleComponent({title}){return<div>{title}</div>}functionuseTitle(){const[title,changeTitle]=useState('默认标题');//createElement返回一个React元素constElement=React.createElement(TitleComponent,{title});返回[Element,changeTitle];}root.render(<Header/>);返回React组件的第二种方式:constroot=ReactDOM.createRoot(document.getElementById('root'));functionHeader(){const[Title,changeTitle]=useTitle();//因为它返回的是一个React组件,所以我们使用元素标签调用return(<divonClick={()=>changeTitle('newtitle')}><Title/></div>)}functionTitleComponent({title}){return<div>{title}</div>}functionuseTitle(){const[title,changeTitle]=useState('默认标题');//这里我们构建一个函数组件constreturnComponent=()=>{return<TitleComponenttitle={title}/>}//这里我们直接返回组件return[returnComponent,changeTitle];}root.render(<Header/>);Customcontent有时我们需要向组件传递自定义内容。比如我们实现了一个Modal组件,有一个OK按钮和一个Cancel按钮,但是Modal显示的内容更加灵活。我们提供了一个props属性,用户可以自定义一个组件传入,用户提供什么,Modal就显示什么,Modal相当于一个容器,那么我们如何实现这个功能呢?第一种实现方法下面是第一种实现方法:functionModal({content}){return(<div>{content}<button>OK</button><button>Cancel</button></div>)}functionCustomContent({text}){return<div>{text}</div>}<Modalcontent={<CustomContenttext="content"/>}/>根据前面的知识我们可以知道content属性这里传入的其实是一个React元素,所以Modal组件内部是用{}渲染的。第二个实现,但第一个,并不总能解决需求。有时,我们可能会使用组件内部的值。比如一个倒计时组件Timer仍然提供了一个属性content用于自定义时间的显示样式。时间由Timer组件内部处理,显示样式完全由用户自定义。这时候我们可以选择传入A组件:functionTimer({content:Content}){const[time,changeTime]=useState('0');useEffect(()=>{setTimeout(()=>{changeTime((newDate).toLocaleTimeString())},1000)},[time])return(<div><Contenttime={time}/></div>)}functionCustomContent({time}){return<divstyle={{border:'1pxsolid#ccc'}}>{time}</div>}<Timercontent={CustomContent}/>在这个例如,我们可以看到在一个React组件CustomContent中传入了content属性,而CustomContent组件会在time属性中传入,我们是基于这个约定来开发CustomContent组件的。在Timer组件内部,因为传入了组件,所以使用<Contenttime={time}/>进行渲染。在第三种实现方式中,当面对第二种实现方式的需求时,除了上述实现方式之外,还有一种技术叫做renderprops,它比第二种方式更为常用。我们仍然以Timer组件为例:functionTimer({renderContent}){const[time,changeTime]=useState('0');useEffect(()=>{setTimeout(()=>{changeTime((newDate).toLocaleTimeString())},1000)},[time])//这里直接调用传入的renderContent函数return(<div>{renderContent(time)}</div>)}functionCustomContent({time}){return<divstyle={{border:'1pxsolid#ccc'}}>{time}</div>}root.render(<计时器renderContent={(time)=>{return<CustomContenttime={time}/>}}/>);由于我们传入了一个函数,所以我们将content属性的名称更改为renderContent,但它可以任意调用。renderContent传入一个函数,该函数接收时间作为参数并返回一个React元素。在Timer内部,我们直接执行renderContent函数,传入内部处理的时间参数,这样用户就可以使用组件内部的值自定义渲染内容。还有一点,除了放在attribute里,我们还可以放在children里,都是一样的:functionTimer({children}){//...return(<div>{children(time)}</div>)}<Timer>{(time)=>{return<CustomContenttime={time}/>}}</Timer>我们可以根据情况选择合适的输入法。React系列讲解React的源码、ReactAPI背后的实现机制、React的最佳实践、React的发展与历史等,估计有50篇左右。如果喜欢或者有什么灵感,欢迎star。也是对作者的鼓励。</p> </div> </div> <div class="zuowen_sxy"> <div class="prev">上一篇:<a title="Bootstrap注释" href="/webqianduan/188766.html">Bootstrap注释</a> </div> <div class="prev">下一篇:<a title="【MobileDevWeekly#383】一个价值800万美元的“害羞”按钮" href="/webqianduan/188768.html">【MobileDevWeekly#383】一个价值800万美元的“害羞”按钮</a> </div> </div> <div class="related_about"> <div class="related_about_t"><code>React中元素和组件的区别相关文章</code></div> <ul> <li><a href="/jishuluodi/317301.html" target="_blank" title="中元节买手机好不好? ">中元节买手机好不好? </a></li> <li><a href="/jishuluodi/317211.html" target="_blank" title="中元节前买手机好还是中元节后买手机好? ">中元节前买手机好还是中元节后买手机好? </a></li> <li><a href="/jishuluodi/316554.html" target="_blank" title="中元节有哪些禁忌呢? ">中元节有哪些禁忌呢? </a></li> <li><a href="/jishuluodi/315754.html" target="_blank" title="中元节的禁忌是真是假? ">中元节的禁忌是真是假? </a></li> <li><a href="/jishuluodi/315046.html" target="_blank" title="中元节鬼节真的有鬼吗">中元节鬼节真的有鬼吗</a></li> <li><a href="/jishuluodi/314652.html" target="_blank" title="中元节期间可以网上买东西吗? ">中元节期间可以网上买东西吗? </a></li> <li><a href="/jishuluodi/313808.html" target="_blank" title="中元节有哪些禁忌? ">中元节有哪些禁忌? </a></li> <li><a href="/jishuluodi/312836.html" target="_blank" title="中元节是什么时候? ">中元节是什么时候? </a></li> <li><a href="/jishuluodi/312520.html" target="_blank" title="中元节出生的人被称为天台">中元节出生的人被称为天台</a></li> <li><a href="/shumafazhan/296775.html" target="_blank" title="Moto全球首发! 2亿像素和1元硬币一样大:比IMX707">Moto全球首发! 2亿像素和1元硬币一样大:比IMX707</a></li> <li><a href="/shumafazhan/293296.html" target="_blank" title="人眼的光圈、像素和ISO是多少? ">人眼的光圈、像素和ISO是多少? </a></li> <li><a href="/shujuyingyong/288459.html" target="_blank" title="HBase存储文件大小的影响因素和优化方法">HBase存储文件大小的影响因素和优化方法</a></li> <li><a href="/shujuyingyong/288199.html" target="_blank" title="MongoDB数据量的影响因素和优化策略">MongoDB数据量的影响因素和优化策略</a></li> <li><a href="/shujuyingyong/288051.html" target="_blank" title="MongoDB集合大小的影响因素和优化方法">MongoDB集合大小的影响因素和优化方法</a></li> <li><a href="/shujuyingyong/286918.html" target="_blank" title="MongoDB并发连接数的影响因素和优化方法">MongoDB并发连接数的影响因素和优化方法</a></li> <li><a href="/shujuyingyong/286736.html" target="_blank" title="MongoDB单表数据量的影响因素和优化策略">MongoDB单表数据量的影响因素和优化策略</a></li> <li><a href="/shujuyingyong/286048.html" target="_blank" title="Redis读取速度的影响因素和优化方法">Redis读取速度的影响因素和优化方法</a></li> <li><a href="/shujuyingyong/284549.html" target="_blank" title="Redis读写速度的影响因素和优化方法">Redis读写速度的影响因素和优化方法</a></li> <li><a href="/shujuyingyong/284217.html" target="_blank" title="Redis客户端连接数的影响因素和优化方法">Redis客户端连接数的影响因素和优化方法</a></li> <li><a href="/shujuyingyong/283542.html" target="_blank" title="Redis缓存数据量的影响因素和优化策略">Redis缓存数据量的影响因素和优化策略</a></li> </ul> </div> </div> <div class="main-right"> <div class="right_fix"> <div class="r_con"> <div class="r_title">最新推荐</div> <ul> <li><em>1</em><a href="/kejifunen/353351.html" title="智能可穿戴医疗保健设备必须考虑的设计要素和挑战" target="_blank">智能可穿戴医疗保健设备必须考虑的设计要素和挑战</a></li> <li><em>2</em><a href="/jishuluodi/334550.html" title="为什么中元节晚上不能出去?这有什么科学依据吗? " target="_blank">为什么中元节晚上不能出去?这有什么科学依据吗? </a></li> <li><em>3</em><a href="/jishuluodi/333906.html" title="中元节的简称是什么? " target="_blank">中元节的简称是什么? </a></li> <li><em>4</em><a href="/jishuluodi/333519.html" title="2023年中元节7月15日是什么时候? " target="_blank">2023年中元节7月15日是什么时候? </a></li> <li><em>5</em><a href="/jishuluodi/333310.html" title="中元节和十月初一是什么意思? " target="_blank">中元节和十月初一是什么意思? </a></li> <li><em>6</em><a href="/jishuluodi/332490.html" title="7月14日,为什么叫中元节呢? " target="_blank">7月14日,为什么叫中元节呢? </a></li> <li><em>7</em><a href="/jishuluodi/332118.html" title="农历中元节是什么时候? " target="_blank">农历中元节是什么时候? </a></li> <li><em>8</em><a href="/jishuluodi/331283.html" title="中元节晚上可以出去吗? " target="_blank">中元节晚上可以出去吗? </a></li> <li><em>9</em><a href="/jishuluodi/331197.html" title="中元节期间可以出去旅游吗? " target="_blank">中元节期间可以出去旅游吗? </a></li> <li><em>10</em><a href="/jishuluodi/330977.html" title="7月15日是中元节,为什么又叫“鬼节”呢? " target="_blank">7月15日是中元节,为什么又叫“鬼节”呢? </a></li> </ul> </div> <div class="r_con"> <div class="r_title">猜你喜欢</div> <ul class="you_like"> <li><em>1</em><a href="/jishuluodi/330577.html" title="中元节的由来及注意事项? " target="_blank">中元节的由来及注意事项? </a></li> <li><em>2</em><a href="/jishuluodi/330557.html" title="中元节马上就要到了,有哪些禁忌? " target="_blank">中元节马上就要到了,有哪些禁忌? </a></li> <li><em>3</em><a href="/jishuluodi/330112.html" title="为什么中元节南北时间不同? " target="_blank">为什么中元节南北时间不同? </a></li> <li><em>4</em><a href="/jishuluodi/329031.html" title="什么是中元节? " target="_blank">什么是中元节? </a></li> <li><em>5</em><a href="/jishuluodi/328123.html" title="中元节期间可以出去办事吗? " target="_blank">中元节期间可以出去办事吗? </a></li> <li><em>6</em><a href="/jishuluodi/327121.html" title="中元节开车走远合适吗? " target="_blank">中元节开车走远合适吗? </a></li> <li><em>7</em><a href="/jishuluodi/326996.html" title="中元节是农历还是阳历? " target="_blank">中元节是农历还是阳历? </a></li> <li><em>8</em><a href="/jishuluodi/326957.html" title="为什么7月14日不是中元节? " target="_blank">为什么7月14日不是中元节? </a></li> <li><em>9</em><a href="/jishuluodi/326540.html" title="北方和南方的中元节有什么区别? " target="_blank">北方和南方的中元节有什么区别? </a></li> <li><em>10</em><a href="/jishuluodi/325700.html" title="中元节什么时候开始、什么时候结束? " target="_blank">中元节什么时候开始、什么时候结束? </a></li> <li><em>11</em><a href="/jishuluodi/325686.html" title="中元节为什么要持续两天? " target="_blank">中元节为什么要持续两天? </a></li> <li><em>12</em><a href="/jishuluodi/325437.html" title="中元节是十四号还是十五号? " target="_blank">中元节是十四号还是十五号? </a></li> <li><em>13</em><a href="/jishuluodi/325178.html" title="中元节有哪些禁忌呢? 7月15日是鬼节的正式日子,也是鬼门大" target="_blank">中元节有哪些禁忌呢? 7月15日是鬼节的正式日子,也是鬼门大</a></li> <li><em>14</em><a href="/jishuluodi/324855.html" title="为什么各地的中元节时间不同? " target="_blank">为什么各地的中元节时间不同? </a></li> <li><em>15</em><a href="/jishuluodi/323630.html" title="中元节前适合旅游吗? " target="_blank">中元节前适合旅游吗? </a></li> <li><em>16</em><a href="/jishuluodi/323535.html" title="南方为什么要在7月14日过中元节? " target="_blank">南方为什么要在7月14日过中元节? </a></li> <li><em>17</em><a href="/jishuluodi/322097.html" title="中元节为什么不能洗头? " target="_blank">中元节为什么不能洗头? </a></li> <li><em>18</em><a href="/jishuluodi/321638.html" title="中元节期间不宜做什么? " target="_blank">中元节期间不宜做什么? </a></li> <li><em>19</em><a href="/jishuluodi/320877.html" title="中元节餐桌上不宜放哪些菜肴? " target="_blank">中元节餐桌上不宜放哪些菜肴? </a></li> <li><em>20</em><a href="/jishuluodi/319848.html" title="中元节手机价格会下降吗? " target="_blank">中元节手机价格会下降吗? </a></li> </ul> </div> </div> </div> </div> <div class="related_article"></div> <div class="footer"> <p>Copyright © 2012-2022 程序源 版权所有<a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">豫ICP备2022028201号</a></p> <p>重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。 如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。</p> </div> <!-- 应用插件标签 start --> <!-- 应用插件标签 end --> </body> </html>