React的组件通信

组件之间进行通信的情况:

 父组件向子组件通信

 子组件向父组件通信

 兄弟组件之间通信

 发布者-订阅者模式

一、父组件向子组件通信

React数据流动是单向的,数据必须从一方传到另一方。在react中,父组件可以通过向子组件传递props,完成父子组件通信。


class Parent extends Components{

this.state={

message: 'hello'

};


componentDidMount(){

setTimeout(()=>{

this.setState({

message: 'world'

});

},2000);

}


render(){

return

}

}


class Child extends Component{

render(){

return

{this.props.message}

}

}



如果父与子之间不止一个层级,如祖孙关系,可以通过...(es6运算符)将父组件的信息,以更简洁的方式传递给更深层级的子组件。而且这种方式不用考虑性能问题,通过babel转义后的...性能与原生一致,且上级组件props和state改变,会导致组件本身和其子组件的生命周期改变。


二、子组件向父组件通信

子组件向父组件通信,也需要父组件向子组件传递props,只是父组件传递的,是作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中。


class Parent extends Component{

this.state = {

message: 'hello'

};

transferMsg(msg){

this.setState({

message

});

}

render(){

return 

           

child msg: {this.state.message}

            this.transferMsg(msg)} />

}

}


class Child extends Component{

componentDidMount(){

setTimeOut( () => {

this.props.transferMsg('world')

},2000)

}

render(){

return

child

}

}


上面的例子中,将父组件的 transferMsg 函数通过props传递给子组件,得益于箭头函数,保证了子组件在调用transferMsg 函数时,其内部的this仍指向父组件。


三、兄弟组件之间通信

对于没有直接关联联系的两个节点,总也能找到它们共同的父组件,如果这两个节点child1,child2要通信,可以先通过child1向父组件通信,再由父组件向child2通信。


class Parent extends Component{

this.state = {

msg: 'hello'

};

transferMsg(msg) {

this.setState({

      msg

    });

  }

componentDidUpdate(){

console.log('Parent update');

}

render() {

return(

this.transferMsg(msg)} />

    );

  }

}


class Child_1 extends Component{

  componentDidMount() {

    setTimeout(() => {

      this.props.transferMsg('world')

    }, 2000);

  }

  componentDidUpdate() {

    console.log('Child_1 update');

  }

  render() {

    return

     

child_1 component

  }


class Child_2 extends Component{

  componentDidUpdate() {

    console.log('Child_2 update');

  }

  render() {

    return   

child_2 component: {this.props.msg}

  }

}

}


除了层层组件传递props,也可以使用context。context是一个全局变量,像是一个大容器,在任何地方都可以访问到,我们可以把要通信的信息放在context上,然后在其他组件中可以随意取到。但是React官方不建议使用大量context,尽管他可以减少逐层传递,但是当组件结构复杂的时候,我们并不知道context是从哪里传过来的,而且context是一个全局变量,全局变量是导致应用走向混乱的罪魁祸首。


四、发布者-订阅者模式

发布者-订阅者模式也叫观察者模式,大量使用在各类框架类库的设计中。发布者发布事件,订阅者监听事件并作出反应,对于上面的代码,我们可以引入一小个模块,使用观察者模式进行改造。在componentDidMount事件中,如果组件挂载完成,订阅事件;在组件卸载的时候,在componentwillUnmount事件中取消对事件的订阅。


import eventProxy from '../eventProxy'

class Parant extends Component{

render(){

return(

)

}

}

//componentDidUpdate、render方法与上例一致

class Child_1 extends Component{

componentDidMount(){

setTimeOut(()=>{

//发布msg事件

eventProxy.trigger('msg','end')

},1000)

}

}

//componentDidUpdate方法与上例一致

class Child_2 extends Component{

state={

msg:'start'

}

componentDidMount(){

//监听msg事件

eventProxy.on('msg',(msg)=>{

this.setState({

msg

})

})

}

render(){

return

child_2 component: {this.state.msg}

}

}


我们在child_2组件的componentDidMount中订阅了msg事件,并在child_1的componentDidMount中,在1s后发布了msg事件,child_2组件对msg事件做出响应,更新了自身的state,在整个通讯过程中,只改变了child_2的state,因此只有child_2和child_2_1的生命周期被触发。

而上述eventProxy中,总共有on、one、off、trigger这四个函数:

on、one:on与one函数用于订阅者监听相应的事件,并将事件响应时的函数作为参数,on与one的唯一区别就是,使用one进行订阅的函数,只会触发一次,而使用on进行订阅的函数,每次事件发生相应时都会被触发。

trigger:trigger用于发布者发布事件,将除第一参数(事件名)的其他参数,作为新的参数,触发使用one与on进行订阅的函数。

off:用于解除订阅了某个事件的所有函数。

你可能感兴趣的:(React的组件通信)