久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx

如何解決React中組件通信問題-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)如何解決React中組件通信問題,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

專業(yè)領(lǐng)域包括成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)電子商務(wù)商城網(wǎng)站建設(shè)、微信營銷、系統(tǒng)平臺開發(fā), 與其他網(wǎng)站設(shè)計及系統(tǒng)開發(fā)公司不同,創(chuàng)新互聯(lián)的整合解決方案結(jié)合了幫做網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗和互聯(lián)網(wǎng)整合營銷的理念,并將策略和執(zhí)行緊密結(jié)合,為客戶提供全網(wǎng)互聯(lián)網(wǎng)整合方案。

父子組件

父 → 子

parent組件傳給child組件,符合react的單向數(shù)據(jù)流理念,自上到下傳遞props。

// 父組件
class Parent extends Component {
 constructor() {
  super();
  this.state = {
   value: '',
  }
 }

 handleChange = e => {
  this.value = e.target.value;
 }

 handleClick = () => {
  this.setState({
   value: this.value,
  })
 }

 render() {
  return (
   <div>
    我是parent
    <input onChange={this.handleChange} />
    <div className="button" onClick={this.handleClick}>通知</div>
    <div>
     <Child value={this.state.value} />
    </div> 
   </div>
  );
 }
}
// 子組件
class Child extends Component {
 render() {
  const { value } = this.props;
  return (
   <div>
    我是Child,得到傳下來的值:{value}
   </div>
  );
 }
}

父組件做的就是定義好 state ,定義好事件函數(shù),input onChange 的時候,去緩存 value 值,然后點擊 button 的時候,改變 state , 子組件只負(fù)責(zé)展示 value 。

子 → 父

child 組件通知 parent 組件, 主要是依靠 parent 傳下來的 callback 函數(shù)執(zhí)行,改變 parent 組件的狀態(tài),或者把 child 自己的 state 通知 parent 。分兩種情況:

state 定義在 parent 組件

// parent

class Parent extends Component {
 constructor() {
  super();
  this.state = {
   value: '',
  }
 }

 setValue = value => {
  this.setState({
   value,
  })
 }

 render() {
  return (
   <div>
    <div>我是parent, Value是:{this.state.value}</div> 
    <Child setValue={this.setValue} />
   </div>
  );
 }
}
class Child extends Component {

 handleChange = e => {
  this.value = e.target.value;
 }

 handleClick = () => {
  const { setValue } = this.props;
  setValue(this.value);
 }

 render() {
  return (
   <div>
    我是Child
    <div className="card">
     state 定義在 parent
     <input onChange={this.handleChange} />
     <div className="button" onClick={this.handleClick}>通知</div>
    </div>
   </div>
  );
 }
}

parent 組件把改變 state 的 setValue 函數(shù)傳給 child ,child 組件自己處理內(nèi)部的狀態(tài)(這里是表單的value值),當(dāng) child 組件分發(fā)消息的時候, 執(zhí)行 parent 的 setValue 函數(shù),從而改變了 parent 的 state,state發(fā)生變化, parent 組件執(zhí)行 re-render 。

state 定義在 child 組件

// parent

class Parent extends Component {

 onChange = value => {
  console.log(value, '來自 child 的 value 變化');
 }

 render() {
  return (
   <div>
    <div>我是parent
    <Child onChange={this.onChange} />
   </div>
  );
 }
}
class Child extends Component {

 constructor() {
  super();
  this.state = {
   childValue: ''
  }
 }

 childValChange = e => {
  this.childVal = e.target.value;
 }

 childValDispatch = () => {
  const { onChange } = this.props;
  this.setState({
   childValue: this.childVal,
  }, () => { onChange(this.state.childValue) })
 }

 render() {
  return (
   <div>
    我是Child
    <div className="card">
     state 定義在 child
     <input onChange={this.childValChange} />
     <div className="button" onClick={this.childValDispatch}>通知</div>
    </div>
   </div>
  );
 }
}

有時候 state 是需要定義在 child 組件的,比如彈窗, CheckBox 這種開關(guān)性質(zhì)的,邏輯是重復(fù)的,state 定義在組件內(nèi)部更好維護, 復(fù)用性更好。但是 child 的 state 是需要告知我的 parent 組件的, 同樣還是執(zhí)行 parent 傳下來的 change 函數(shù)。

兄弟組件

有時候可能出現(xiàn)頁面中的某兩部分通信,比如省市的級聯(lián)選擇,點擊 button 改變顏色等等,組件并不是父子級,沒有嵌套關(guān)系的時候。這種時候通常是依賴共有的頂級 Container 處理或者第三方的狀態(tài)管理器。其實原理都是相通的,兄弟 A 的 value 發(fā)生變化,分發(fā)的時候把 value 值告訴一個中間者 C ,C 會自動告知 B,實現(xiàn) B 的自動render 。

利用共有的Container

// container
class Container extends Component {
 constructor() {
  super();
  this.state = {
   value: '',
  }
 }

 setValue = value => {
  this.setState({
   value,
  })
 }

 render() {
  return (
   <div>
    <A setValue={this.setValue}/>
    <B value={this.state.value} />
   </div>
  );
 }
}
// 兄弟A
class A extends Component {

 handleChange = (e) => {
  this.value = e.target.value;
 }

 handleClick = () => {
  const { setValue } = this.props;
  setValue(this.value);
 }

 render() {
  return (
   <div className="card">
    我是Brother A, <input onChange={this.handleChange} />
    <div className="button" onClick={this.handleClick}>通知</div>
   </div>
  )
 }
}
// 兄弟B
const B = props => (
 <div className="card">
  我是Brother B, value是:
  {props.value}
 </div>
);
export default B;

組件 A 中的表單 value 值,告知了父級 Container 組件(通過 setValue 函數(shù)改變 state),組件 B 依賴于 Container 傳下來的 state,會做出同步更新。這里的中間者是 Container。

利用Context

上面的方式,如果嵌套少還可以,如果嵌套特別多,比如一級導(dǎo)航欄下的二級導(dǎo)航欄下的某個按鈕,要改變頁面中 content 區(qū)域的 table 里的某個列的值...他們同屬于一個 page 。這樣傳遞 props 就會很痛苦,每一層組件都要傳遞一次。

// 頂級公共組件
class Context extends Component {

 constructor() {
  super();
  this.state = {
   value: '',
  };
 }

 setValue = value => {
  this.setState({
   value,
  })
 }

 getChildContext() { // 必需
  return { 
   value: this.state.value,
   setValue: this.setValue,
  };
 }
 render() {
  return (
   <div>
    <AParent />
    <BParent />
   </div>
  );
 }
}
// 必需
Context.childContextTypes = {
 value: PropTypes.string,
 setValue: PropTypes.func,
};
// A 的 parent
class AParent extends Component {
 render() {
  return (
   <div className="card">
    <A />
   </div>
  );
 }
}
// A
class A extends Component {

 handleChange = (e) => {
  this.value = e.target.value;
 }

 handleClick = () => {
  const { setValue } = this.context;
  setValue(this.value);
 }

 render() {
  return (
   <div>
    我是parentA 下的 A, <input onChange={this.handleChange} />
    <div className="button" onClick={this.handleClick}>通知</div>
   </div>
  );
 }
}
// 必需
A.contextTypes = {
 setValue: PropTypes.func,
};
// B 的 parent
class BParent extends Component {
 render() {
  return (
   <div className="card">
    <B />
   </div>
  );
 }
}

// B
class B extends Component {

 render() {
  return (
   <div>
    我是parentB 下的 B, value是:
    {this.context.value}
   </div>
  );
 }
}

B.contextTypes = {
 value: PropTypes.string,
};

組件 A 仍是 消息的發(fā)送者,組件 B 是接收者, 中間者是 Context 公有 Container 組件。context是官方文檔的一個 API ,通過 getChildContext 函數(shù)定義 context 中的值,并且還要求 childContextTypes 是必需的。這樣屬于這個 Container 組件的子組件,通過 this.context 就可以取到定義的值,并且起到跟 state 同樣的效果。中間者其實還是 Container,只不過利用了上下文這樣的 API ,省去了 props 的傳遞。另外:這個功能是實驗性的,未來可能會有所改動。

發(fā)布訂閱

這種一個地方發(fā)送消息,另一個地方接收做出變化的需求,很容易想到的就是觀察者模式了。具體的實現(xiàn)會有很多種,這里我們自己寫了一個 EventEmitter 的類(其實就是仿照 node 中的 EventEmitter 類),如果不了解觀察者,可以看我的另一篇文章 觀察者模式 。

// 發(fā)布訂閱類
class EventEmitter {
 _event = {}

 // on 函數(shù)用于綁定
 on(eventName, handle) {
  let listeners = this._event[eventName];
  if(!listeners || !listeners.length) {
   this._event[eventName] = [handle];
   return;
  }
  listeners.push(handle);
 }
 // off 用于移除
 off(eventName, handle) {
  let listeners = this._event[eventName];
  this._event[eventName] = listeners.filter(l => l !== handle);
 }
 // emit 用于分發(fā)消息
 emit(eventName, ...args) {
  const listeners = this._event[eventName];
  if(listeners && listeners.length) {
   for(const l of listeners) {
    l(...args);
   }
  }
 }
}
const event = new EventEmitter;
export { event };
// Container
import A from './a';
import B from './b';

const Listener = () => {
 return (
  <div>
   <A />
   <B />
  </div>
 );
};
export default Listener;
// 兄弟組件 A
import { event } from './eventEmitter';

class A extends Component {

 handleChange = e => {
  this.value = e.target.value;
 }

 handleClick = () => {
  event.emit('dispatch', this.value);
 }

 render() {
  return (
   <div className="card">
    我是Brother A, <input onChange={this.handleChange} />
    <div className="button" onClick={this.handleClick}>通知</div>
   </div>
  )
 }
}
// 兄弟組件 B
import { event } from './eventEmitter';

class B extends Component {
 state = {
  value: ''
 }

 componentDidMount() {
  event.on('dispatch', this.valueChange);
 }

 componentWillUnmount() {
  event.off('dispatch', this.valueChange);
 }

 valueChange = value => {
  this.setState({
   value,
  })
 }

 render() {
  return (
   <div className="card">
    我是Brother B, value是:
    {this.state.value}
   </div>
  );
 }
}

仍然是組件 A 用于分發(fā)消息,組件 B 去接收消息。這里的中間者其實就是 event 對象。需要接收消息的 B 去訂閱 dispatch 事件,并把回調(diào)函數(shù) valueChange 傳入,另外 B 定義了自己的 state,方便得到 value 值的時候自動渲染。組件 A 其實就是把內(nèi)部的表單 value 在點擊的時候分發(fā),發(fā)布事件,從而 B 中的 valueChange 執(zhí)行,改變 state。這種方式比較方便,也更直觀,不需要借助 Container 組件去實現(xiàn),省去了很多邏輯。

Redux || Mobx

Redux 或者 Mobx 是第三方的狀態(tài)管理器,是這里我們通信的中間者。大型項目最直接的就是上庫... 更方便,更不容易出錯。 但其實小項目就沒什么必要了。東西比較多,這里不再闡述它們的實現(xiàn)和做了什么。

關(guān)于“如何解決React中組件通信問題”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.js-pz168.com,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

網(wǎng)站題目:如何解決React中組件通信問題-創(chuàng)新互聯(lián)
路徑分享:http://www.js-pz168.com/article2/gseoc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站服務(wù)器托管Google商城網(wǎng)站電子商務(wù)全網(wǎng)營銷推廣

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計
久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx
国产99精品在线观看| 色综合视频二区偷拍在线| 先锋影音欧美| 欧美一区二区私人影院日本| 中文字幕精品一区二区三区精品| 午夜视频久久久久久| 成人一道本在线| 欧美自拍资源在线| 7777精品伊人久久久大香线蕉经典版下载| 中文字幕成人av| 免费美女久久99| 成人在线观看91| 欧美亚日韩国产aⅴ精品中极品| 久久久久久久国产精品影院| 午夜成人在线视频| 99久久99久久精品国产片果冻| 日韩免费电影一区二区| 日韩欧美亚洲国产精品字幕久久久| 日韩美女啊v在线免费观看| 激情偷乱视频一区二区三区| 国产精品一区二区三区免费| 欧美手机在线视频| 亚洲视频中文字幕| 国产馆精品极品| 日本中文不卡| 久久青草国产手机看片福利盒子 | 在线精品观看国产| 国产清纯白嫩初高生在线观看91 | 日韩精品自拍偷拍| 午夜精品一区二区三区电影天堂 | 91一区二区在线| 色88888久久久久久影院野外| 国产肉丝袜一区二区| 久久精品国产亚洲5555| 免费中文日韩| 精品国产一区二区三区四区四| 日韩国产欧美三级| 精品久久一区二区三区蜜桃| 欧美一区二区三区日韩| 性做久久久久久免费观看欧美| 99se婷婷在线视频观看| 欧美日韩另类一区| 一区二区三区.www| 成人av资源网| 69精品人人人人| 日韩经典一区二区| 黄色99视频| www久久精品| 久久99精品国产麻豆婷婷| 欧美日韩在线一二三| 久久综合狠狠综合久久综合88 | 天堂一区二区在线免费观看| 电影午夜精品一区二区三区| 欧美狂野另类xxxxoooo| 婷婷开心激情综合| 久久综合狠狠综合久久综青草| 精品噜噜噜噜久久久久久久久试看| 日韩成人免费在线| 日产精品一线二线三线芒果| 国产亚洲欧美一级| 成人午夜大片免费观看| 欧美三级电影在线观看| 亚洲大片在线观看| 久久综合一区| 国产日本欧洲亚洲| 成人av中文字幕| 欧美猛男男办公室激情| 免费日本视频一区| 亚洲v国产v| 亚洲欧美韩国综合色| 超碰97人人人人人蜜桃| 精品国产99国产精品| 国产一区二区三区日韩| 欧美最猛性xxxxx直播| 亚洲动漫第一页| 久久久久久国产精品一区| 欧美国产日韩a欧美在线观看| 高清国产一区二区三区| 欧美人与性动xxxx| 久久99最新地址| 色偷偷久久一区二区三区| 亚洲影院久久精品| 免费看污久久久| 中文字幕在线观看一区二区| 99中文字幕| 久久女同互慰一区二区三区| 波波电影院一区二区三区| 日韩一区二区免费视频| 国产精品自拍三区| 91超碰这里只有精品国产| 久久成人av少妇免费| 欧美中文字幕一区二区三区| 免费三级欧美电影| 91国偷自产一区二区开放时间 | 亚洲韩国精品一区| 日日噜噜噜噜夜夜爽亚洲精品| 亚洲九九爱视频| 另类视频在线观看+1080p| 日韩理论电影院| 精品999在线观看| 亚洲天堂久久久久久久| 久久av免费观看| 亚洲柠檬福利资源导航| 欧美理论一区二区| 一区二区视频在线看| 日韩国产伦理| 亚洲成av人片在线观看无码| 亚洲欧洲精品一区二区| 婷婷中文字幕综合| 在线观看网站黄不卡| 久久国产精品99久久人人澡| 欧美影片第一页| 国产一区二区三区免费播放| 91精品国产91热久久久做人人 | 日韩极品在线观看| 欧美影院一区二区| 国产米奇在线777精品观看| 欧美一区二区三区在线| 成人av集中营| 国产欧美一区二区精品性| 国产 高清 精品 在线 a| 中文字幕色av一区二区三区| 免费国产一区二区| 午夜欧美电影在线观看| 欧美在线影院一区二区| 国产九九视频一区二区三区| 日韩亚洲欧美在线观看| 91日韩久久| 中文字幕中文字幕一区| 日本一区二区视频| 奇米精品一区二区三区在线观看一| 欧美日韩综合不卡| 成人av资源在线| 国产精品人妖ts系列视频| 欧美日韩精品免费看| 日本午夜一本久久久综合| 欧美日高清视频| 91丨九色丨蝌蚪富婆spa| 日韩理论片在线| 中文字幕免费在线不卡| 国产一区二区三区在线观看免费 | 成人激情视频网站| 亚洲国产成人自拍| 天天爽天天狠久久久| 久久精品国产亚洲aⅴ| 精品美女一区二区| 狠狠色噜噜狠狠色综合久| 香蕉乱码成人久久天堂爱免费| 精品视频1区2区| 97久久精品人人做人人爽50路| 中文字幕一区二区三区在线不卡| 相泽南亚洲一区二区在线播放| 久久精品国产久精国产爱| 精品国产乱码久久久久久1区2区| 国产女人水真多18毛片18精品| 亚洲一区二区av在线| 欧美美女直播网站| 国产高清精品一区二区| 亚洲va中文字幕| 日韩一区二区免费在线观看| 国产综合动作在线观看| 日韩激情中文字幕| 精品久久国产字幕高潮| 欧洲亚洲一区| 国产美女视频91| 中文字幕一区二区三中文字幕| 最新不卡av| 91色porny| 天天影视涩香欲综合网| 日韩欧美久久一区| 美女视频久久| 国产美女av一区二区三区| 国产精品久久久久一区二区三区| 永久免费精品视频网站| 97久久超碰精品国产| 亚洲成国产人片在线观看| 日韩欧美美女一区二区三区| 女同一区二区| 国产成人av一区二区三区在线观看| 国产精品国产三级国产普通话三级| 色婷婷精品久久二区二区蜜臀av | 捆绑紧缚一区二区三区视频| 久久久99精品久久| 亚洲女人毛片| 99精品欧美一区| 日韩av不卡一区二区| 久久久国产午夜精品| 正在播放久久| 99热国产免费| 麻豆久久久久久久| 国产精品久久久久久久岛一牛影视 | 精品综合久久久久久8888| 中文字幕精品在线不卡| 欧美三级电影在线看| 精品国产一区二区三区麻豆免费观看完整版 | 日本麻豆一区二区三区视频| 国产午夜精品久久久久久久| 91久久精品一区二区三| 国产乱码精品一区二区三区卡 | 亚洲一区av在线|