这篇文章主要讲解了React中组合组件的使用方法,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。
这种模式本质上解决的是组件之间传值的问题。但是它对于传值以及一些内部操控的逻辑封装得更严密。
场景:希望减少上下级组件之间props的传递,简单来说就是不用传做显式地传值,来达到组件之间相互通信的目的
举例来说,某些界面中应该有Tabs这样的组件,由Tab和TabItem组成,点击每个TabItem,该TabItem会高亮,
那么Tab和TabItem自然要进行沟通。很自然的写法是像下面这样
<TabItem active={true} onClick={this.onClick}>One</TabItem>
<TabItem active={false} onClick={this.onClick}>Two</TabItem>
<TabItem active={false} onClick={this.onClick}>Three</TabItem>
这样的缺点很明显:
但是,组件之间的交互我们又不希望通过props或者context来实现。希望用法如下面一样简洁。
<Tabs>
<TabItem>第一</TabItem>
<TabItem>第二</TabItem>
<TabItem>第三</TabItem>
</Tabs>
组件之间通过隐秘的方式进行通信,但这里的隐秘实际上是对props的操作在一个地方进行管理。
明白了要实现的交互,和代码层面要实现的效果,就可以开始动手了。
TabItem组件有两个关键的props: active(表明当前是否应高亮),onTabClick(自己被点击时调用的回调函数),
TabItem由于是每个Tab页面的容器,它只负责把props.children渲染出来,所以用函数式组件即可。
export const TabItem = props => {
const { active, onTabClick, children } = props
const style = {
color: active ? 'red' : 'green',
cursor: 'pointer'
}
return <>
<h2 style={style} onClick={onTabClick}>
{children}
</h2>
</>
}
我们再来回顾一下想到达到的效果:
<Tabs>
<TabItem>第一</TabItem>
<TabItem>第二</TabItem>
<TabItem>第三</TabItem>
</Tabs>
使用组件时要避免传递props的缺点,那么在哪里传递呢?自然是是Tabs组件。但上面并没有传入props啊。
Tabs 虽然可以访问到props里边的children,但是到手的children已经是现成的如果直接改它的话,会出问题。
不可以直接改children的话,我们就把children复制一份,然后改这个复制过来的children,再渲染出去,就ok啦!
下面来看Tabs的实现:
class Tabs extends React.Component {
state={
activeIndex: 0
}
render() {
const { activeIndex } = this.state
const newChildren = React.Children.map(this.props.children, (child, index) => {
if (child.type) {
// 复制并修改children
return React.cloneElement(child, {
active: activeIndex === index,
onTabClick: () => this.setState({activeIndex: index})
})
} else {
return child
}
})
return <div className="tabs">
{newChildren}
</div>
}
}
这里需要用到React不常用的api:
使用React.Children.map
来对props.children
进行遍历。
而React.cloneElement
可以复制某个元素,第一个参数是被复制的元素,第二个参数我们可以把想传入的props加进去,也就是这个时机,
我们将active和onTabClick传入。实现最终效果。
看完上述内容,是不是对React中组合组件的使用方法有进一步的了解,如果还想学习更多内容,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。