5.React中元件通訊問題

PursuitFreeDom發表於2018-03-27

1.父元件傳遞值給子元件

想必這種大家都是知道的吧!都想到了用我們react中的props,那麼我在這簡單的寫了小demo,請看
父元件

class Parent extends Component{
  render() {
    return (
      <Child text="Hello" />
    )
  }
}

子元件

class Child extends Component{
  render(){
    return (
      <p>{ this.props.text }</p>
    )
  }
}

2.子元件傳值給父元件

相必大家在這裡估計得想一想吧!那麼由我同樣寫個小demo來告訴大家,理解了其實也不難哦
父元件

class Parent extends Component {
  constructor(props) {
    super(props); 
    this.state = {
      someKey: `world`
    };
  }
  fn(newState) {
    this.setState({ someKey: newState });
  }
  render() {
    return (
      <div>
        <Child pfn={this.fn.bind(this)} />
        <p>{this.state.someKey}</p>
      </div>
    );
  }
}

子元件

class Child extends Component {
  constructor(props) {
    super(props); 
    this.state = {
      newState: `Hello`
    };
  }
  someFn() {
    this.props.pfn(this.state.newState);//這裡就是傳值給父元件
  }
  render() {
    return (
      <div onClick={ this.someFn.bind(this) }>點我</div>
    );
  }
}

通過回撥函式進行向父元件傳值,並繫結父元件的this this.fn.bind(this)

3.有任何巢狀關係的元件之間傳值

如果元件之間沒有任何關係,元件巢狀層次比較深(個人認為 2 層以上已經算深了),或者你為了一些元件能夠訂閱、寫入一些訊號,不想讓元件之間插入一個元件,讓兩個元件處於獨立的關係。對於事件系統,這裡有 2 個基本操作步驟:訂閱(subscribe)/監聽(listen)一個事件通知,併傳送(send)/觸發(trigger)/釋出(publish)/傳送(dispatch)一個事件通知那些想要的元件。

下面講介紹 3 種模式來處理事件,你能 點選這裡 來比較一下它們。

簡單總結一下:

(1) Event Emitter/Target/Dispatcher

特點:需要一個指定的訂閱源

// to subscribe
otherObject.addEventListener(‘click’, function() { alert(‘click!’); });
// to dispatch
this.dispatchEvent(‘click’);

(2) Publish / Subscribe

特點:觸發事件的時候,你不需要指定一個特定的源,因為它是使用一個全域性物件來處理事件(其實就是一個全域性廣播的方式來處理事件)

// to subscribe
globalBroadcaster.subscribe(‘click’, function() { alert(‘click!’); });
// to dispatch
globalBroadcaster.publish(‘click’);

(3) Signals

特點:與Event Emitter/Target/Dispatcher相似,但是你不要使用隨機的字串作為事件觸發的引用。觸發事件的每一個物件都需要一個確切的名字(就是類似硬編碼類的去寫事件名字),並且在觸發的時候,也必須要指定確切的事件。(看例子吧,很好理解)

// to subscribe
otherObject.clicked.add(function() { alert(‘click’); });
// to dispatch
this.clicked.dispatch();

在處理事件的時候,需要注意:
在 componentDidMount 事件中,如果元件掛載(mounted)完成,再訂閱事件;當元件解除安裝(unmounted)的時候,在 componentWillUnmount 事件中取消事件的訂閱。

看了上面所述,是否有所感悟
例如通過事件來進行非父子元件間的通訊,如果操作不是很多,我們可以自己動手簡單實現以下哦!
下面我簡單的寫了一個,請看

簡單實現了一下 subscribe 和 dispatch

let EventEmitter = {
  _events: {},
  dispatch: function (event, data) {
    if (!this._events[event]) { // 沒有監聽事件
      return;
    }
    for (var i = 0; i < this._events[event].length; i++) {
      this._events[event][i](data);
    }
  },
  subscribe: function (event, callback) {
    // 建立一個新事件陣列
    if (!this._events[event]) {
      this._events[event] = [];
    }
    this._events[event].push(callback);
  }
};

otherObject.subscribe(`namechanged`, (data) => console.log(data.name));
this.dispatch(`namechanged`, { name: `John` });

是不是現在覺得元件通訊其實也沒那麼難懂吧,加油吧,騷年

相關文章