老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

如何解決React中組件通信問題

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

創新互聯建站長期為超過千家客戶提供的網站建設服務,團隊從業經驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯網生態環境。為張店企業提供專業的成都網站設計、網站建設,張店網站改版等技術服務。擁有十多年豐富建站經驗和眾多成功案例,為您定制開發。

父子組件

父 → 子

parent組件傳給child組件,符合react的單向數據流理念,自上到下傳遞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 (
   
    我是parent          通知
    
          
     
  );  } }
// 子組件
class Child extends Component {
 render() {
  const { value } = this.props;
  return (
   
    我是Child,得到傳下來的值:{value}    
  );  } }

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

子 → 父

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

state 定義在 parent 組件

// parent

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

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

 render() {
  return (
   
    
我是parent, Value是:{this.state.value}
          
  );  } }
class Child extends Component {

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

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

 render() {
  return (
   
    我是Child           state 定義在 parent            通知
    
   
  );  } }

parent 組件把改變 state 的 setValue 函數傳給 child ,child 組件自己處理內部的狀態(這里是表單的value值),當 child 組件分發消息的時候, 執行 parent 的 setValue 函數,從而改變了 parent 的 state,state發生變化, parent 組件執行 re-render 。

state 定義在 child 組件

// parent

class Parent extends Component {

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

 render() {
  return (
   
    
我是parent         
  );  } }
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 (
   
    我是Child           state 定義在 child            通知
           );  } }

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

兄弟組件

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

利用共有的Container

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

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

 render() {
  return (
   
             
  );  } }
// 兄弟A
class A extends Component {

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

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

 render() {
  return (
   
    我是Brother A, 
    通知
   
  )
 }
}
// 兄弟B
const B = props => (
 
  我是Brother B, value是:
  {props.value}
 
);
export default B;

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

利用Context

上面的方式,如果嵌套少還可以,如果嵌套特別多,比如一級導航欄下的二級導航欄下的某個按鈕,要改變頁面中 content 區域的 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 (
   
             
  );  } } // 必需 Context.childContextTypes = {  value: PropTypes.string,  setValue: PropTypes.func, };
// A 的 parent
class AParent extends Component {
 render() {
  return (
   
    
   
  );
 }
}
// A
class A extends Component {

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

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

 render() {
  return (
   
    我是parentA 下的 A,      通知
      );  } } // 必需 A.contextTypes = {  setValue: PropTypes.func, };
// B 的 parent
class BParent extends Component {
 render() {
  return (
   
    
   
  );
 }
}

// B
class B extends Component {

 render() {
  return (
   
    我是parentB 下的 B, value是:     {this.context.value}    
  );  } } B.contextTypes = {  value: PropTypes.string, };

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

發布訂閱

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

// 發布訂閱類
class EventEmitter {
 _event = {}

 // on 函數用于綁定
 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 用于分發消息
 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 (
  
          
 ); }; 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 (
   
    我是Brother A, 
    通知
   
  )
 }
}
// 兄弟組件 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 (
   
    我是Brother B, value是:
    {this.state.value}
   
  );
 }
}

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

Redux || Mobx

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

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


當前題目:如何解決React中組件通信問題
文章URL:http://www.xueling.net.cn/article/gghedc.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 中文字幕乱码熟妇五十中出 | 亚洲高清国产拍精品影院 | 亚洲日本欧美综合在线一 | 国农村精品国产自线拍 | 国产美女在线精品免费观看 | 99热爱久久99热爱九九热爱 | 伊人久色 | 中文字幕亚洲在线观看 | 好硬啊进得太深了A片无码公司 | 婷婷久久综合九色综合97最多收藏 | J97久久国产亚洲精品超碰热 | 黄色视网站 | 亚洲欧美在线视频观看 | 日韩激情无码AV一区二区 | 国产精品乱码一区二区三区视频 | 99久久精品免费看蜜桃的推荐词 | av资源站最稳定的资源站 | 国产超薄肉丝袜在线 | 国产在线观看成人 | 亚洲一区二区三区日韩 | 天天狠天天狠天天鲁 | 欧美日韩色老头 | 97中文字幕在线观看 | 亚洲欧美综合精品成人网站 | 蜜桃av鲁一鲁一鲁一鲁 | 国产精品久久人妻无码免费看 | 成人免费av在线 | 99热久RE这里只有精品小草 | 欧美精品一区二区三区视频 | 国产成熟妇人高潮A片 | 国产美女操b在线观看 | 亚洲日韩爆乳中文字幕欧美 | 成人激情在线观看 | 鲁一鲁亚洲无线码 | 欧美成人高清视频 | 综合人妻久久一区二区精品 | 国产无遮挡又黄又爽高潮 | 国产欧美亚洲日本 | 国产亚洲色欲色一色WWW | 成年日韩片av在线网站 | 亚洲免费网站观看视频 |