美文网首页
2. 组件通信(父子/爷孙)

2. 组件通信(父子/爷孙)

作者: Jason_Shu | 来源:发表于2019-01-25 19:44 被阅读0次

今天我们通过「龟兔赛跑」的故事,来理解React中的组件通讯。

class App extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      allTime1: 0, // 兔子跑完全程所用时间
      allTime2: 0, // 乌龟跑完全程所用时间
    }
    
    this.startTime = new Date();  // 记录开始时间
  }
  
  success1() {
    this.setState({
      allTime1: new Date() - this.startTime
    });
  }
  
  success2() {
    this.setState({
      allTime2: new Date() - this.startTime
    });
  }
  
  render() {
    return(
      <div>
        <div className="time-wrapper">
          <Time1 time={this.state.allTime1}/>
          <Time2 time={this.state.allTime2}/>
        </div>
        <Track1 success={this.success1.bind(this)}/>
        <Track2 success={this.success2.bind(this)}/>
        
      </div>
    );
  }
}

// 记录兔子用时组件
class Time1 extends React.Component {
  constructor(props) {
    super(props);
  }
  
  render() {
    return(
      <div className="rabbit">
        <span>🐇</span>
        <span>{this.props.time}</span>
      </div>
    );
  }
}

// 记录乌龟用时组件
class Time2 extends React.Component {
  constructor(props) {
    super(props);
  }
  
  render() {
    return(
      <div className="tortoise">
        <span>🐢</span>
        <span>{this.props.time}</span>
      </div>
    );
  }
}


class Track1 extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      style: {
        transform: 'translateX(0%)'
      }
    };
    
    // 初试位置
    let position = 0;
    
    // 计时器
    let time = setInterval(() => {
      position += 30;
      
      if(position >= 100) {
        position = 100;
        clearInterval(time);
        this.props.success();
      }
      this.setState({
        style: {
          transform: `translateX(${position}%)`
        }
      });
    }, 1000);
  }
  render() {
    return(
      <div className="track-wrapper">
        <div style={this.state.style}>🐇</div>
        <div className="track"></div>
      </div>
    );
  }
}

class Track2 extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      style: {
        transform: 'translateX(0%)'
      }
    };
    
    // 初试位置
    let position = 0;
    
    // 计时器
    let time = setInterval(() => {
      position += 20;
      
      if(position >= 100) {
        position = 100;
        clearInterval(time);
      
        this.props.success();
      }
      this.setState({
        style: {
          transform: `translateX(${position}%)`
        }
      });
    }, 1000);
  }
  render() {
    return(
      <div className="track-wrapper">
        <div style={this.state.style}>🐢</div>
        <div className="track"></div>
      </div>
    );
  }
}

render();

function render() {
  ReactDOM.render(<App/>, document.querySelector('#root'));
}
父子组件结构图.png 起始状态.png 结束状态.png

如上图,是组件之间的结构图,相当于一棵「树结构」。首先在「Track1」和「Track2」中执行由「App」传给他俩的「success」回调函数来记录所花时间,「App」中的state保存了「Track1」和「Track2」中执行的时间,然后传到「Time1」和「Time2」中,「Time1」和「Time2」通过「props」拿到时间渲染到组件内。

image.png

以上图「Track2」为例,当「Track2」中的乌龟跑到终点后,便调用「success」函数(图中1处),这个函数是由「App」组件传给「Track2」的,可以通知「App」乌龟跑完所需要的时间,记录到「Track2」的「this.state」里。再由「App」将「this.state」里面记录的时间传给「Time2」(图中2处)。

我再「Track1」和「Trank2」组件上加一层「PlayGround」组件。

class App extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      allTime1: 0, // 兔子跑完全程所用时间
      allTime2: 0, // 乌龟跑完全程所用时间
    }
    
    this.startTime = new Date();  // 记录开始时间
  }
  
  success1() {
    this.setState({
      allTime1: new Date() - this.startTime
    });
  }
  
  success2() {
    this.setState({
      allTime2: new Date() - this.startTime
    });
  }
  
  render() {
    return(
      <div>
        <div className="time-wrapper">
          <Time1 time={this.state.allTime1}/>
          <Time2 time={this.state.allTime2}/>
        </div>
        <PlayGround 
          success1={this.success1.bind(this)}
          success2={this.success2.bind(this)}
          />
        
      </div>
    );
  }
}

// 记录兔子用时组件
class Time1 extends React.Component {
  constructor(props) {
    super(props);
  }
  
  render() {
    return(
      <div className="rabbit">
        <span>🐇</span>
        <span>{this.props.time}</span>
      </div>
    );
  }
}

// 记录乌龟用时组件
class Time2 extends React.Component {
  constructor(props) {
    super(props);
  }
  
  render() {
    return(
      <div className="tortoise">
        <span>🐢</span>
        <span>{this.props.time}</span>
      </div>
    );
  }
}


class Track1 extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      style: {
        transform: 'translateX(0%)'
      }
    };
    
    // 初试位置
    let position = 0;
    
    // 计时器
    let time = setInterval(() => {
      position += 30;
      
      if(position >= 100) {
        position = 100;
        clearInterval(time);
        this.props.success();
      }
      this.setState({
        style: {
          transform: `translateX(${position}%)`
        }
      });
    }, 1000);
  }
  render() {
    return(
      <div className="track-wrapper">
        <div style={this.state.style}>🐇</div>
        <div className="track"></div>
      </div>
    );
  }
}

class Track2 extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      style: {
        transform: 'translateX(0%)'
      }
    };
    
    // 初试位置
    let position = 0;
    
    // 计时器
    let time = setInterval(() => {
      position += 20;
      
      if(position >= 100) {
        position = 100;
        clearInterval(time);
      
        this.props.success();
      }
      this.setState({
        style: {
          transform: `translateX(${position}%)`
        }
      });
    }, 1000);
  }
  render() {
    return(
      <div className="track-wrapper">
        <div style={this.state.style}>🐢</div>
        <div className="track"></div>
      </div>
    );
  }
}

class PlayGround extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return( 
      <div className='playground'>
        <Track1 success={this.props.success1}/>
        <Track2 success={this.props.success2}/>
      </div>
    )
  }
}

render();

function render() {
  ReactDOM.render(<App/>, document.querySelector('#root'));
}
爷孙组件结构图.png

跟上面的功能相似,还是「App」把回调函数「success」传到「PlayGround」组件,再由「PlayGround」组件传到「Track1」和「Track2」,「Track1」和「Track2」中调用「success」函数把时间记录在「App」中,然后把记录的时间从「App」中传到「Time1」和「Time2」。

相关文章

  • Vue实现组件间通信

    父子组件通信on('xxx',function(){}) 爷孙组件通信eventbusvar eventBus =...

  • Vue如何实现组件通信?

    Vue组件通信的三种情况: 父子通信 爷孙通信 兄弟通信 父子通信:父组件使用Prop向子组件传递数据,子组件通过...

  • 2. 组件通信(父子/爷孙)

    今天我们通过「龟兔赛跑」的故事,来理解React中的组件通讯。 如上图,是组件之间的结构图,相当于一棵「树结构」。...

  • 组件通信- 父子/爷孙

    下面通过一个龟兔赛跑案例来帮助理解组件通信特别说明:如果组件不需要内部状态就用函数,否则就用classclass组...

  • Vue3全局组件通信之provide / inject

    顾名思义,爷孙组件是比 父子组件通信[https://vue3.chengpeiquan.com/communic...

  • react 组件通信

    概述 react中的组件通信问题,根据层级关系总共有四种类型的组件通信:父子组件、爷孙组件、兄弟组件和任意组件。前...

  • Vue3全局组件通信之EventBus

    全局组件通信 全局组件通信是指,两个任意的组件,不管是否有关联(e.g. 父子、爷孙)的组件,都可以直接进行交流的...

  • React入门 5:组件通信 - 任意组件通信

    本篇文章内容包括: 任意两个组件之间如何通信 发布订阅模式 Redux 1. 回顾父子/爷孙组件通信 任何一个函数...

  • React02-组件通信

    React父子组件之间如何通信父组件传一个函数给子组件,子组件在适当的时候调用这个函数React爷孙组件之间如何通...

  • vue中的组件通信

    一、组件通信(组件传值) 1.1父子组件通信 1.2子父组件通信 1.3非父子组件通信(兄弟组件通信)

网友评论

      本文标题:2. 组件通信(父子/爷孙)

      本文链接:https://www.haomeiwen.com/subject/bhvmjqtx.html