前言
在React项目的开发中经常会遇到这样一个场景:嵌套组件与被嵌套组件的通信。
比如Tab组件啊,或者下拉框组件。
场景
这里应用一个最简单的Tab组件来呈现这个场景。
import React, { Component, PropTypes } from 'react' class Tab extends Component { static propTypes = { children: PropTypes.node } render() { return ( <ul> {this.props.children} </ul> ) } } class TabItem extends Component { static propTypes = { name: PropTypes.string, active: PropTypes.bool, onClick: PropTypes.func } handleClick = () => { this.props.onClick(this.props.name) } render() { return ( <li onClick={this.handleClick} className={this.props.active "color: #ff0000">需求的变更与缺陷的暴露在上述场景下应用上述方案是没有问题的,但是我们通常用的Tab没有这么简单,比如当点击武汉这个TabItem时,武汉地区的美食也要展示出来。
这种场景下就需要修改TabItem组件为:
class TabItem extends Component { static propTypes = { name: PropTypes.string, active: PropTypes.bool, onClick: PropTypes.func, children: PropTypes.node } handleClick = () => { this.props.onClick(this.props.name) } render() { return ( <li onClick={this.handleClick} className={this.props.active "htmlcode">export default class Area extends Component { state = { activeName: '' } handleClick = (name) => { this.setState({ activeName: name }) } render() { return ( <Tab> <TabItem onClick={this.handleClick} active={this.state.activeName === '武汉'} name={'武汉'} > 武汉的美食,这里有一大堆jsx代码 </TabItem> <TabItem onClick={this.handleClick} active={this.state.activeName === '上海'} name={'上海'} > 武汉的美食,这里有一大堆jsx代码 </TabItem> <TabItem onClick={this.handleClick} active={this.state.activeName === '北京'} name={'北京'} > 武汉的美食,这里有一大堆jsx代码 </TabItem> </Tab> ) } }这里的Area使用TabItem的时候已经没办法用 数组+map 的形式去写了。
因为这里有大量的jsx在这里,如果那样去写,代码的可读性将会非常糟糕。
那么用上面的写法写的时候,就会出现一个问题,就是onClick在不断重复,active的判断也在不断重复。
尝试掩盖active判断重复的问题
这个比较容易,修改代码如下:
class TabItem extends Component { static propTypes = { name: PropTypes.string, activeName: PropTypes.string, onClick: PropTypes.func, children: PropTypes.node } handleClick = () => { this.props.onClick(this.props.name) } render() { return ( <li onClick={this.handleClick} className={this.props.activeName === this.props.name "color: #ff0000">尝试掩盖onClick不断重复的问题想要onClick不重复,那么就不能将其写在TabItem上,而是应该写在Tab上。
那么这个地方就得用到事件冒泡的机制。
将onClick写在Tab上,然后根据捕获的事件消息,获取target的class是否为switchBtn,然后得到target的text。
再将这个text赋值为activeName。并且你还得期望点击的switchBtn的内的结构不那么复杂,最好是就只有一个文本。
如果需求还要给Tab项的切换按钮每个都加上图标,那么你还得看这个事件的target是不是这个图标。那么又需要做更多的处理了。
想一想就觉得麻烦。
一般在这种情况下,脑子里唯一的想法就是,就这样吧,这个onClick重复就重复吧,没什么大不了的。
连我自己都懒得写这部分代码了。嵌套组件与被嵌套组件的通信:React.Children与React.cloneElement
实际上要解决上面的问题,只需要一个东西就好了,那就是嵌套组件能传递值给被嵌套组件的props,比如onClick。
那么先上一份代码吧。
class TabItem extends Component { static propTypes = { name: PropTypes.string, activeName: PropTypes.string, onClick: PropTypes.func, children: PropTypes.node } handleClick = () => { this.props.onClick(this.props.name) } render() { return ( <li onClick={this.handleClick} className={this.props.activeName === this.props.name "color: #ff0000">React.ChildrenReact.Children是专门用来处理this.props.children这个东西的工具。
通常props.children可以是任何变量类型:数组、对象、文本或者其他的一些类型,但是我们这里使用
React.Children.map(this.props.children,(child)=>{ // *** })无论this.props.children的类型是什么都不会报错。
这里只是用了React.children的map函数,实际上它还有foreach,count以及only的玩法。
foreach就不解释了,很容易理解是干嘛的。
count就是得到被嵌套组件的数量。
only就是返回被嵌套的组件,并且只能有一个被嵌套的组件,否则会抛异常。React.cloneElement
先看下面这段代码
const child= <Child value={1} /> const newChild=React.cloneElement(child,{ name:'额外的props' },'123')newChild的值为:
<Child value={1} name='额外的props' > 123 </Child>可以很明显看到,React.cloneElement的就相当克隆一个组件,然后可以传给它额外的props和children。
总结
对于简单的嵌套组件用最开始的方法其实已经够了。
但是对于复杂的嵌套组件为了更好更方便的使用,往往需要与被嵌套的组件进行通信。
而我们可以使用React.Children和React.cloneElement来解决这个问题。
华山资源网 Design By www.eoogi.com
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 第五街的士高《印度激情版》3CD [WAV+CUE][2.4G]
- 三国志8重制版哪个武将智力高 三国志8重制版智力武将排行一览
- 三国志8重制版哪个武将好 三国志8重制版武将排行一览
- 三国志8重制版武将图像怎么保存 三国志8重制版武将图像设置方法
- 何方.1990-我不是那种人【林杰唱片】【WAV+CUE】
- 张惠妹.1999-妹力新世纪2CD【丰华】【WAV+CUE】
- 邓丽欣.2006-FANTASY【金牌大风】【WAV+CUE】
- 饭制《黑神话》蜘蛛四妹手办
- 《燕云十六声》回应跑路:年内公测版本完成95%
- 网友发现国内版《双城之战》第二季有删减:亲亲环节没了!
- 邓丽君2024-《漫步人生路》头版限量编号MQA-UHQCD[WAV+CUE]
- SergeProkofievplaysProkofiev[Dutton][FLAC+CUE]
- 永恒英文金曲精选4《TheBestOfEverlastingFavouritesVol.4》[WAV+CUE]
- 群星《国风超有戏 第9期》[320K/MP3][13.63MB]
- 群星《国风超有戏 第9期》[FLAC/分轨][72.56MB]