亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

React中嵌套組件與被嵌套組件的通信過程

2019-11-19 13:30:47
字體:
供稿:網(wǎng)友

前言

在React項目的開發(fā)中經(jīng)常會遇到這樣一個場景:嵌套組件與被嵌套組件的通信。
比如Tab組件啊,或者下拉框組件。

場景

這里應用一個最簡單的Tab組件來呈現(xiàn)這個場景。

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 ? 'active' : 'noActive'}>    {this.props.name}   </li>  ) }}export default class Area extends Component { state = {  activeName: '' } handleClick = (name) => {  this.setState({   activeName: name  }) } render() {  return (   <Tab>    {['武漢', '上海', '北京'].map((item) => <TabItem onClick={this.handleClick} active={this.state.activeName === item} name={item} />)}   </Tab>  ) }}

這里有Tab,TabItem和Area三個組件,其中Tab為嵌套組件,TabItem為被嵌套組件,Area為使用它們的組件。
在上述場景中,點擊哪個TabItem項時,就將這個TabItem項激活。

以上方案算是嵌套組件最常用的方案了。

需求的變更與缺陷的暴露

在上述場景下應用上述方案是沒有問題的,但是我們通常用的Tab沒有這么簡單,比如當點擊武漢這個TabItem時,武漢地區(qū)的美食也要展示出來。

這種場景下就需要修改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 ? 'active' : 'noActive'}>    <span className='switchBtn'>{this.props.name}</span>    <div className={this.props.active ? 'show' : 'hide'}>     {this.props.children}    </div>   </li>  ) }}

然后沿用上述方案,那么就需要改變Area組件為:

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的時候已經(jīng)沒辦法用 數(shù)組+map 的形式去寫了。

因為這里有大量的jsx在這里,如果那樣去寫,代碼的可讀性將會非常糟糕。

那么用上面的寫法寫的時候,就會出現(xiàn)一個問題,就是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 ? 'active' : 'noActive'}>    <span className='switchBtn'>{this.props.name}</span>    <div className={this.props.active ? 'show' : 'hide'}>     {this.props.children}    </div>   </li>  ) }}export default class Area extends Component { state = {  activeName: '' } handleClick = (name) => {  this.setState({   activeName: name  }) } render() {  return (   <Tab>    <TabItem onClick={this.handleClick} activeName={this.state.activeName} name={'武漢'} >     武漢的美食,這里有一大堆jsx代碼    </TabItem>    <TabItem onClick={this.handleClick} activeName={this.state.activeName} name={'上海'} >     武漢的美食,這里有一大堆jsx代碼    </TabItem>    <TabItem onClick={this.handleClick} activeName={this.state.activeName} name={'北京'} >     武漢的美食,這里有一大堆jsx代碼    </TabItem>   </Tab>  ) }}

嘗試掩蓋onClick不斷重復的問題

想要onClick不重復,那么就不能將其寫在TabItem上,而是應該寫在Tab上。

那么這個地方就得用到事件冒泡的機制。

將onClick寫在Tab上,然后根據(jù)捕獲的事件消息,獲取target的class是否為switchBtn,然后得到target的text。
再將這個text賦值為activeName。

并且你還得期望點擊的switchBtn的內(nèi)的結(jié)構(gòu)不那么復雜,最好是就只有一個文本。

如果需求還要給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 ? 'active' : 'noActive'}>    <span className='switchBtn'>{this.props.name}</span>    <div className={this.props.active ? 'show' : 'hide'}>     {this.props.children}    </div>   </li>  ) }}class Tab extends Component { static propTypes = {  children: PropTypes.node,  onClickItem: PropTypes.func,  activeName: PropTypes.string } render() {  return (   <ul>    {     React.Children.map(this.props.children,(child)=>{      if (child.type === TabItem) {       return React.cloneElement(child, {        // 把父組件的props.name賦值給每個子組件(父組件傳值給子組件)        activeName: this.props.activeName,        // 父組件的方法掛載到props.onClick上,以便子組件內(nèi)部通過props調(diào)用        onClick: this.props.onClickItem       })      } else {       return child      }     })    }   </ul>  ) }}export default class Area extends Component { state = {  activeName: '' } handleClick = (name) => {  this.setState({   activeName: name  }) } render() {  return (   <Tab activeName={this.state.activeName} onClick={this.handleClick} >    <TabItem name={'武漢'} >     武漢的美食,這里有一大堆jsx代碼    </TabItem>    <TabItem name={'上海'} >     武漢的美食,這里有一大堆jsx代碼    </TabItem>    <TabItem name={'北京'} >     武漢的美食,這里有一大堆jsx代碼    </TabItem>   </Tab>  ) }}

通過這種方式,我們發(fā)現(xiàn)在使用Tab和TabItem時會變得非常簡單。

那么接下來讓我們介紹一下解決嵌套組件通信這個問題的關(guān)鍵:React.Children.map和React.cloneElement。
React.Children

React.Children是專門用來處理this.props.children這個東西的工具。

通常props.children可以是任何變量類型:數(shù)組、對象、文本或者其他的一些類型,但是我們這里使用

React.Children.map(this.props.children,(child)=>{ // ***})

無論this.props.children的類型是什么都不會報錯。

這里只是用了React.children的map函數(shù),實際上它還有foreach,count以及only的玩法。

foreach就不解釋了,很容易理解是干嘛的。
count就是得到被嵌套組件的數(shù)量。
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。

總結(jié)

對于簡單的嵌套組件用最開始的方法其實已經(jīng)夠了。

但是對于復雜的嵌套組件為了更好更方便的使用,往往需要與被嵌套的組件進行通信。

而我們可以使用React.Children和React.cloneElement來解決這個問題。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
精品一区二区三区免费播放| 91亚洲精品视频| 品久久久久久久久久96高清| 中文字幕电影在线观看| 精品国产制服丝袜高跟| 国产一区二区在线观看免费播放| 国产午夜久久av| 中文在线资源观看网站视频免费不卡| 日韩在线观看第一页| 久久精品中文字幕免费mv| 三区四区不卡| 国产另类xxxxhd高清| 日韩美女免费线视频| 韩国成人福利片在线播放| 国产精品免费在线| 天天做天天摸天天爽国产一区| 美女扒开腿让男人桶爽久久软| 日韩亚洲电影在线| 日日躁夜夜躁白天躁晚上躁91| 视频在线观看一区二区| 秋霞午夜理伦电影在线观看| 国产拍欧美日韩视频二区| 成人免费视频app| 亚洲一级二级三级| 你懂的在线网址| 国产成人精品一区| 在线观看免费一区| 欧美午夜不卡| 在线手机福利影院| 亚洲精品免费在线观看视频| 亚洲 国产 日韩 综合一区| 日韩欧美视频在线播放| 国产欧美一区二区三区网站| 日本少妇xxx| 国产强伦人妻毛片| 伊人成人免费视频| 国产精品中出一区二区三区| 女人扒开腿免费视频app| 国产在线播放一区二区三区| 老司机在线永久免费观看| 日本欧美韩国| 91激情在线观看| 狠狠色丁香婷综合久久| 日韩黄色在线免费观看| 日韩在线视频线视频免费网站| 欧美女人交a| www.av在线.com| 成人久久久精品乱码一区二区三区| 欧美新色视频| 亚洲精品一区二区在线看| 久久久精品2019中文字幕之3| 欧美精品中文字幕一区二区| 热re久久精品国产99热| 国产精品久久久一区二区| 亚洲人体偷拍| 亚洲国产91精品在线观看| av在线免费观看网| 九九久久精品这里久久网| 日韩一区二区三区免费视频| 在线一级成人| 日韩免费特黄一二三区| eeuss影院网站免费观看| 免费成人深夜夜行网站| 亚洲啪啪综合av一区二区三区| 五月婷婷六月香| 毛片毛片女人毛片毛片| 国产超碰精品| 日本一区二区三区四区| 日韩中文在线中文网在线观看| 91精品综合久久久久久久久久久| 蜜臀久久99精品久久久无需会员| 神马国产精品影院av| 久久在线视频免费观看| 久久久这里只有精品视频| 91精品久久久久| 婷婷激情综合| 91久久精品国产91久久性色tv| 亚洲熟妇av乱码在线观看| 免费看电影在线| 欧美中文字幕亚洲一区二区va在线| 成人免费在线| 国产精品欧美久久久久天天影视| 99高清免费国产自产拍| 亚洲欧美日韩国产中文专区| 国产小视频在线高清播放| 手机av在线网| 国产亚洲精品码| 欧美 日韩 综合| 午夜亚洲性色福利视频| 精品动漫3d一区二区三区免费版| 男人操女人在线观看| 两个人看的免费完整在线观看| 久久精品国产2020观看福利| 色哟哟精品丝袜一区二区| 特黄aaaaaaaaa毛片免费视频| 国产乱子精品一区二区在线观看| 美女把尿口扒开让男人桶在线观看| 精品剧情v国产在线观看在线| 91精品黄色片免费大全| 户外露出一区二区三区| 亚洲第一av色| 中文字幕在线视频区| 高清欧美精品xxxxx| 亚洲成人精品久久| avhd101老司机| 精品一区电影国产| 黄色免费av网站| 精品视频在线观看免费观看| 日韩亚洲欧美一区| 日韩精品福利网站| 最新一本之道波多野结衣| 日本午夜精品视频在线观看| 最新版天堂资源在线| 国产亚洲精品久久久久久牛牛| 亚洲裸色大胆大尺寸艺术写真| 亚洲一区二区视频在线播放| 暖暖影院日本高清...免费| 成人伊人222| 亚洲欧美综合色| 国产伦理一区二区三区| 国产亚洲激情在线| 亚洲欧美自拍偷拍色图| 中文字幕一区二区精品| 日本成人免费| 国产一级片网站| 五月婷婷亚洲综合| 亚洲国产欧美日韩| 97成人超碰视| 美女网站视频在线| 天堂影视av| 日韩一级毛片| xxx国产在线观看| 麻豆一区二区三区在线观看| 456亚洲影院| 少妇精69xxtheporn| 精品国产乱码久久久久久影片| 精品麻豆剧传媒av国产九九九| 国产区av在线| 亚洲网在线观看| 亚洲精品一区二区三区蜜桃| 欧美日本一区二区三区| 九色porny91| 一区二区三区在线免费视频| 怡红院男人天堂| 欧美国产一区二区| 精品人妻人人做人人爽夜夜爽| а√天堂中文在线资源bt在线| 特一级黄色大片| 手机福利在线| 蜜桃视频一区二区| 精品影院一区| 中文字幕一区二区三区免费视频| 亚洲欧美日韩一二三区| 日韩欧美在线中字| 亚洲免费在线视频一区 二区| 亚洲丝袜自拍清纯另类| 国产日韩精品一区二区浪潮av| 在线视频这里只有精品| 国外成人在线视频网站| 色老头在线一区二区三区| 久久亚洲精精品中文字幕| 69堂免费视频| 伊人久久亚洲美女图片| 日本dvd播放| 日韩欧美国产成人一区二区| 天堂在线中文网官网| 亚洲国产精品精华素| 丝袜国产在线| 国产精品久久久久久久久动漫| 国模gogo一区二区大胆私拍| 日韩电影免费观看中文字幕| 成人午夜精品久久久久久久蜜臀| 成人羞羞视频免费| 免费观看国产成人| 午夜视频在线观| 自拍偷拍欧美| 国产羞羞视频在线播放| 亚洲一级电影视频| 91丝袜美腿高跟国产极品老师| 欧美日韩国产亚洲沙发| 污网站在线免费看| 中文字幕在线观看第二页| 免费毛片在线看片免费丝瓜视频| 国产精品久久一级| 欧美中文字幕精在线不卡| 成人日韩在线电影| 日本在线视频www鲁啊鲁| 日韩在线观看高清| 丝袜视频国产在线播放| 欧美一区二区免费在线观看| 日韩在线播放av| 亚洲大胆人体在线| 围产精品久久久久久久| 日韩在线卡一卡二| 疯狂揉花蒂控制高潮h| 污视频免费在线观看网站| 3d蒂法精品啪啪一区二区免费| 四虎在线视频免费观看| 国产精品久久久久久一区二区三区| 国内成+人亚洲+欧美+综合在线| 国产成人自拍网| 久久精品成人av| 伊人伊人av电影| 欧美5-7sexvideos处| 日韩欧美亚洲日产国产| 欧美最猛性xxxx| av在线www| 国产亚洲a∨片在线观看| 久久久久久久久久久久久久久久久久| 黄页视频在线免费观看| 正在播放国产精品| 日本一区视频在线| www网站在线观看| 男人av资源站| 亚洲一区二区四区| 亚洲丁香久久久| 亚洲日本aⅴ片在线观看香蕉| 国产乱码精品一区二区三区中文| 麻豆一区二区麻豆免费观看| 亚洲成av人电影| 欧美喷水一区二区| 亚洲欧洲日韩av| 成年人免费在线观看网站| 蜜臀av一区二区| 免费一级suv好看的国产网站| 91在线中字| 特色特色大片在线| 亚洲天堂狠狠干| 小黄文在线观看| 呻吟揉丰满对白91乃国产区| 国产三级精品在线| 亚州成人av在线| 午夜精品一区二区在线观看的| 黄色欧美日韩| 欧美国产日韩二区| 久久久视频精品| 国产一区二区不卡视频在线观看| 国产91精品精华液一区二区三区| 亚洲精品有码在线| 99精品在线直播| 国产精品变态另类虐交| 国产成人综合一区二区三区| 波多野结衣亚洲一区| 久久久久久久久久久福利| 色鬼7777久久| 欧美性一区二区| 欧美成人日韩| 国产v日韩v欧美v| 国产亚洲精品自在线观看| 成人免费在线观看入口| wwwwwww色| 国产日韩精品视频一区二区三区| 国产 日韩 欧美一区| 色八戒一区二区三区| 26uuu亚洲伊人春色| 天天爱天天做天天操| 亚洲精品乱码久久久久久蜜桃麻豆| 自拍偷拍你懂的| 超级碰碰视频| 日韩熟女一区二区| 成人免费高清在线播放| 国产欧美激情| 神马午夜电影一区二区三区在线观看| 自拍欧美日韩| 日韩avvvv在线播放| wwwwww.欧美系列| 精品久久久久久久久国产字幕| 国产99在线免费| 99热这里只有精品9| 中文字幕的av| 午夜精品福利一区二区三区蜜桃| 成年永久一区二区三区免费视频| 污网站免费在线| 日本一道本久久| 亚洲女同精品视频| 国产无遮挡又黄又爽| 亚洲精品爱爱久久| 人妻无码一区二区三区久久99| 一区二区三区回区在观看免费视频| 免费观看在线综合| 色视频一区二区三区| 欧美一区二区三区在线| 一区二区三区在线观看网站| 免费av中文字幕| 999av视频| 中文字幕字幕中文在线中不卡视频| 欧美欧美欧美| 最新国产精品拍自在线播放| 精品视频高潮| 久久99久久久久久| 精品日韩欧美| www在线观看免费| 欧美性潮喷xxxxx免费视频看| 日韩在线观看电影完整版高清免费| 欧美久久久影院| vam成人资源在线观看| 少妇特黄一区二区三区| 精品国产鲁一鲁一区二区三区| 色偷偷色偷偷色偷偷在线视频| 四虎地址8848jia| 一区二区视频在线观看免费的| 欧美图片欧美激情欧美精品| 欧美日韩一区二区三区四区| 日本视频中文字幕一区二区三区| 欧美大秀在线观看| 日韩一本精品| 欧美偷拍一区二区| 中文一区二区在线观看| 中文字幕亚洲电影| 欧美性受xxx黑人xyx性爽| 亚洲精品久久久久久下一站| 日本免费不卡一区二区| av免费不卡国产观看| avav免费在线观看| 宅男噜噜噜66国产免费观看| 中文字幕一区二区三区乱码不卡| 婷婷国产在线| 蜜臀久久99精品久久久久久9| 欧美激情亚洲综合一区| 精品国产成人亚洲午夜福利| 永久在线免费观看| 国产美女裸体无遮挡免费视频| 色一情一交一乱一区二区三区| 亚洲黄网站黄| 日本污视频在线观看| 亚洲精品一线| 911美女片黄在线观看游戏| aa亚洲婷婷|