React中元素和组件的区别
时间:2023-03-28 14:53:44
HTML
从问题出发,被问到这样一个问题:我想实现一个useTitle方法。具体使用示例如下:functionHeader(){const[Title,changeTitle]=useTitle();return(changeTitle('newtitle')}>
)}但是在编写useTitle代码时出了点问题:functionTitleComponent({title}){return
{title}
}functionuseTitle(){const[title,changeTitle]=useState('默认标题');constElement=React.createElement(TitleComponent,{title});return[Element.type,changeTitle];}这段代码直接报错,连渲染都渲染不出来。如果是你,你会如何修改这段代码?元素和组件其实这是一个很典型的问题,如何区分和使用元素和组件。元素我们先看看React官方文档中对React元素的介绍:Babel会把JSX翻译成一个叫做React.createElement()的函数调用。下面两个示例代码是完全等价的:constelement=
Hello,world!;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=你好,{name}
;所以如果我们想使用React元素,那么我们应该这样使用Embedded表达式:constname=JoshPerez;constelement=你好,{name}
;component组件呢?组件有两种类型,函数组件和类组件://函数组件functionWelcome(props){returnHello,{props.name}
;}//类组件classWelcomeextendsReact.Component{render(){return你好,{this.props.name}
;那么如何使用组件呢?constelement=;对于组件,我们需要用类似于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(changeTitle('newtitle')}>{Title} )}functionTitleComponent({title}){return
{title}
}functionuseTitle(){const[title,changeTitle]=useState('默认标题');//createElement返回一个React元素constElement=React.createElement(TitleComponent,{title});返回[Element,changeTitle];}root.render(
);返回React组件的第二种方式:constroot=ReactDOM.createRoot(document.getElementById('root'));functionHeader(){const[Title,changeTitle]=useTitle();//因为它返回的是一个React组件,所以我们使用元素标签调用return(
changeTitle('newtitle')}> )}functionTitleComponent({title}){return
{title}
}functionuseTitle(){const[title,changeTitle]=useState('默认标题');//这里我们构建一个函数组件constreturnComponent=()=>{return
}//这里我们直接返回组件return[returnComponent,changeTitle];}root.render(
);Customcontent有时我们需要向组件传递自定义内容。比如我们实现了一个Modal组件,有一个OK按钮和一个Cancel按钮,但是Modal显示的内容更加灵活。我们提供了一个props属性,用户可以自定义一个组件传入,用户提供什么,Modal就显示什么,Modal相当于一个容器,那么我们如何实现这个功能呢?第一种实现方法下面是第一种实现方法:functionModal({content}){return(
{content}
)}functionCustomContent({text}){return
{text}
}
}/>根据前面的知识我们可以知道content属性这里传入的其实是一个React元素,所以Modal组件内部是用{}渲染的。第二个实现,但第一个,并不总能解决需求。有时,我们可能会使用组件内部的值。比如一个倒计时组件Timer仍然提供了一个属性content用于自定义时间的显示样式。时间由Timer组件内部处理,显示样式完全由用户自定义。这时候我们可以选择传入A组件:functionTimer({content:Content}){const[time,changeTime]=useState('0');useEffect(()=>{setTimeout(()=>{changeTime((newDate).toLocaleTimeString())},1000)},[time])return(
)}functionCustomContent({time}){return
{time} }