一、为什么要用组件
项目开发中有一个地图经纬度选择的对话框,这个选择器多处使用到,起初觉得就是复制粘贴的事,也懒得去研究什么父子组件啊什么的,后来被无数次调整搞到自闭,因为一调整就是每一处使用的都得改,实在是太麻烦了,于是才去研究父子组件,把这个地图经纬度选择的功能抽取出去成为一个组件,随调随用,如需要改动,也只需要改这个组件就可以,简直人间天堂
二、子组件获取父组件值、方法
1、父组件:在调用子组件时,把值和方法作为子组件的属性传递过去,如下
<SelectPos choosePoint = {this.choosePoint} longitude={this.state.value.longitude||''} latitude={this.state.value.latitude||''}></SelectPos>
2、子组件:通过this.props.xxx获取父组件传递过来的值或方法(调用父组件的方法)
//获取父组件传递的值
let lat=this.props.latitude,
let lng=this.props.longitude
//调用父组件传递的方法
this.props.choosePoint();
三、父组件获取子组件值、方法
法1
1、父组件中:给子组件添加 onRef={(ref) => { this.child = ref; }}
onRef = (ref) => {
this.child = ref
}
<SelectPos onRef={this.onRef} choosePoint = {this.choosePoint} longitude={this.state.value.longitude||''} latitude={this.state.value.latitude||''}></SelectPos>
2、子组件中:在子组件中添加生命周期的 componentDidMount 这个方法
componentDidMount() {
if (this.props.onRef) {
this.props.onRef(this);
}
}
3、在父组件用 this.child.xxx 的方式拿值
let Longitude =this.child.state.Longitude
this.child.confirmMapSelect();
法2
1、子组件添加属性 ref=‘selector’
<SelectPos ref='selector' choosePoint = {this.choosePoint} longitude={this.state.value.longitude||''} latitude={this.state.value.latitude||''}></SelectPos>
2、在父组件用 this.refs.selector.xxx 的方式拿值
let lng=this.refs.selector.state.lng
this.refs.selector.confirmMapSelect();//调用子组件中的方法
法3
1、在父组件创建ref容器:this.pw = React.createRef()
constructor(props) {
super(props);
// 方法3:创建用来保存ref标识的标签对象的容器
this.pw = React.createRef()
}
2、给子组件添加属性:ref={this.pw}
<SelectPos ref={this.pw} choosePoint = {this.choosePoint} longitude={this.state.value.longitude||''} latitude={this.state.value.latitude||''}></SelectPos>
3、就可以在父组件用 this.pw.current.xxx拿到子组件值和方法
alert(this.pw.current.state.lng);
this.pw.current.confirmMapSelect()
四、完整代码示例
1、父组件(此处父组件是另外一个组件的子组件)
onRef = (ref) => {
this.child = ref
}
confirmMapSelect = () => {
//父组件直接获取子组件传递过来的值
//this.props.value.Longitude = this.child.state.lng;
//this.props.value.Latitude = this.child.state.lat;
//this.setState({
//showMap: false
//});
this.child.confirmMapSelect();//父组件调用子组件的方法
}
choosePoint = (a,b) => {//通过方法获取子组件传递过来的值
this.props.value.Longitude = a;
this.props.value.Latitude = b;
this.setState({
showMap: false
});
}
<Dialog className="no-bac"
visible={this.state.showMap}
onOk={this.confirmMapSelect}
onCancel={this.onCloseMap}
onClose={this.onCloseMap}
closable="esc,mask,close"
title="经纬度定位"
>
<SelectPos onRef={this.onRef} choosePoint = {this.choosePoint} longitude={this.props.value.longitude||''} latitude={this.props.value.latitude||''}></SelectPos>
</Dialog>
2、子组件
state = {
lat:this.props.latitude,//子组件获取父组件传递的值
lng:this.props.longitude
}
componentDidMount() {
this.props.onRef(this);
}
confirmMapSelect = () => {
this.props.choosePoint(this.state.lng, this.state.lat);//这里是子组件调用父组件传递过来的方法,把子组件的值传递给父组件,也可以不这么做
}