HTML 渲染后的样式:
其中 星形好评 与 心形好评 属于子组件 Child,火形好评 属于父组件 Parent
联动关系:
(1)点击 星形好评,改变 星形好评数,同时 火形好评 随之改变,反之不然;
(2)点击 火形好评,改变 火形好评数,同时 心形好评 随之改变,反之不然;
(3)点击 心形好评,仅改变 心形好评数;
方法调用:
(1)通过 子组件调用父组件的方法,实现了 星形好评 对 火形好评 的联动;
(2)通过 父组件调用子组件的方法,实现了 火形好评 对 心形好评 的联动;
一、字符绑定 方式
import React, { Component } from 'react';
import { Rate, Icon, Divider } from 'antd';
class Child extends Component {
constructor(props) {
super(props);
this.state = {
star: 0,
heart: 0,
};
}
componentDidMount() {
// do nothing
}
changeStar = star => {
this.setState({ star });
this.props.parent.reactFire(star);
};
changeHeart = heart => {
this.setState({ heart });
};
reactHeart = heart => {
// invoked by parent
this.setState({ heart });
};
render() {
return (
<>
<Rate value={this.state.star} onChange={this.changeStar} style={{ color: 'green' }} />
<br />
<Rate
value={this.state.heart}
onChange={this.changeHeart}
character={<Icon type="heart" theme="filled" />}
style={{ color: 'orange' }}
/>
</>
);
}
}
class Parent extends Component {
constructor(props) {
super(props);
this.state = { fire: 0 };
}
changeFire = fire => {
this.setState({ fire });
this.refs.childRef.reactHeart(fire);
};
reactFire = fire => {
// invoked by children
this.setState({ fire });
};
render() {
return (
<>
{/* Custom attribute name 'parent' */}
<Child parent={this} ref="childRef" />
<Divider />
<Rate
value={this.state.fire}
onChange={this.changeFire}
character={<Icon type="fire" theme="filled" />}
style={{ color: 'red' }}
/>
</>
);
}
}
export default Parent;
二、React.createRef() 方式
import React, { Component } from 'react';
import { Rate, Icon, Divider } from 'antd';
class Child extends Component {
constructor(props) {
super(props);
this.state = {
star: 0,
heart: 0,
};
}
componentDidMount() {
// do nothing
}
changeStar = star => {
this.setState({ star });
this.props.parent.reactFire(star);
};
changeHeart = heart => {
this.setState({ heart });
};
reactHeart = heart => {
// invoked by parent
this.setState({ heart });
};
render() {
return (
<>
<Rate value={this.state.star} onChange={this.changeStar} style={{ color: 'green' }} />
<br />
<Rate
value={this.state.heart}
onChange={this.changeHeart}
character={<Icon type="heart" theme="filled" />}
style={{ color: 'orange' }}
/>
</>
);
}
}
class Parent extends Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
this.state = { fire: 0 };
}
changeFire = fire => {
this.setState({ fire });
this.childRef.current.reactHeart(fire);
};
reactFire = fire => {
// invoked by children
this.setState({ fire });
};
render() {
return (
<>
{/* Custom attribute name 'parent' */}
<Child parent={this} ref={this.childRef} />
<Divider />
<Rate
value={this.state.fire}
onChange={this.changeFire}
character={<Icon type="fire" theme="filled" />}
style={{ color: 'red' }}
/>
</>
);
}
}
export default Parent;
三、方法绑定 方式
import React, { Component } from 'react';
import { Rate, Icon, Divider } from 'antd';
class Child extends Component {
constructor(props) {
super(props);
this.state = {
star: 0,
heart: 0,
};
}
componentDidMount() {
// Custom method name 'self'
this.props.self(this);
}
changeStar = star => {
this.setState({ star });
this.props.parent.reactFire(star);
};
changeHeart = heart => {
this.setState({ heart });
};
reactHeart = heart => {
// invoked by parent
this.setState({ heart });
};
render() {
return (
<>
<Rate value={this.state.star} onChange={this.changeStar} style={{ color: 'green' }} />
<br />
<Rate
value={this.state.heart}
onChange={this.changeHeart}
character={<Icon type="heart" theme="filled" />}
style={{ color: 'orange' }}
/>
</>
);
}
}
export default class Parent extends Component {
constructor(props) {
super(props);
this.state = { fire: 0 };
}
changeFire = fire => {
this.setState({ fire });
this.childRef.reactHeart(fire);
};
reactFire = fire => {
// invoked by children
this.setState({ fire });
};
render() {
return (
<>
{/* Custom attribute name 'parent' */}
<Child parent={this} self={ref => (this.childRef = ref)} />
<Divider />
<Rate
value={this.state.fire}
onChange={this.changeFire}
character={<Icon type="fire" theme="filled" />}
style={{ color: 'red' }}
/>
</>
);
}
}