今天我们通过「龟兔赛跑」的故事,来理解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」。
网友评论