1. 程式人生 > >react(二):組件的通信

react(二):組件的通信

xtend ans res || react font 函數 很難 好的

對於組件來說,通信無非兩種,父子組件通信,和非父子組件通信

一、父子父子組件通信

  1、父組件給子組件傳值

  對於父組件來說,props是他們之間的媒介

class Parent extends Component{
  state = {
    msg: ‘start‘
  };

  componentDidMount() {
    setTimeout(() => {
      this.setState({
        msg: ‘end‘
      });
    }, 1000);
  }

  render() {
    return <Child_1 msg={this
.state.msg} />; } } class Child_1 extends Component{ render() { return <p>{this.props.msg}</p> } }

子組件通過接受父組件的props來獲取父組件中的數據

  2、子組件給父組件傳值

  途徑是先在父組件中註冊一個回調函數,子組件通過props獲取到這一回調函數並執行

  

class Parent extends Component{
  state = {
    msg: ‘start‘
  };
  
  transferMsg(msg) {
    
this.setState({ msg }); } render() { return <div> <p>child msg: {this.state.msg}</p> <Child_1 transferMsg = {msg => this.transferMsg(msg)} /> </div>; } } class Child_1 extends Component{ componentDidMount() { setTimeout(()
=> { this.props.transferMsg(‘end‘) }, 1000); } render() { return <div> <p>child_1 component</p> </div> } }

  這樣在子組件中用傳參的方式,獲取到子組件中的數據,進而改變了父組件的狀態

  3、祖先組件給後代組件(就是組件之間的嵌套已經超過一層)

  這樣的話也還可以通過props來傳值,但是一層一層的傳有點麻煩,我們可以使用... 運算符(三個點是es6裏面的剩余展開屬性),以更簡潔的方式傳遞給更深層級的子組件。通過這種方式,不用考慮性能的問題,通過 babel 轉義後的 ... 運算符 性能和原生的一致

class Parent extends Component{
  state = {
    msg: ‘start‘
  };

  componentDidMount() {
    setTimeout(() => {
      this.setState({
        msg: ‘end‘
      });
    }, 1000);
  }

  render() {
    return <Child_1 msg={this.state.msg} />;
  }
}

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

二、非父子組件之間的傳值

  對於非父子組件來說缺少連接的紐帶,很難通過props聯系到一起(要是不是很遠的話也能用,但是要是過深就特別麻煩),但是我們可以使用全局的一些機制來實現,比如react提供了一種上下文機制

class Brother1 extends React.Component{
  constructor(props){
    super(props);
    this.state = {}
  }
  
  render(){
    
    return (
      <div>
        <button onClick={this.context.refresh}>
            更新兄弟組件
        </button>
      </div>
    )
  }
}
Brother1.contextTypes = {
  refresh: React.PropTypes.any
}
class Brother2 extends React.Component{
  constructor(props){
    super(props);
    this.state = {}
  }
  
  render(){
    return (
      <div>
         {this.context.text || "兄弟組件未更新"}
      </div>
    )
  }
}
Brother2.contextTypes = {
  text: React.PropTypes.any
}
class Parent extends React.Component{
  constructor(props){
    super(props);
    this.state = {}
  }
  
  getChildContext(){
    return {
      refresh: this.refresh(),
      text: this.state.text,
      }
    }
  
  refresh(){
    return (e)=>{
      this.setState({
        text: "兄弟組件溝通成功",
      })
    }
  }
  render(){
    return (
      <div>
        <h2>兄弟組件溝通</h2>
        <Brother1 />
        <Brother2 text={this.state.text}/>
      </div>
    )
  }
}
Parent.childContextTypes = {
  refresh: React.PropTypes.any,
  text: React.PropTypes.any,
}

使用方法

使用getChildContext方法將屬性傳遞給子組件,並使用childContextTypes聲明傳遞數據類型,子組件中需要顯式地使用contextTypes聲明需要用到的屬性的數據類型。

需要傳遞進context參數才可以在constructor方法中使用context,要不然React將會報錯。

在組件中,通過this.context訪問context中的屬性或方法。

未完待續。。。

關於組件之間的通信還有更好的方式,比如說用redux來管理數據流,之後單獨整理關於redux的部分。

react(二):組件的通信