父子组件通信
数据流
- react是单向数据流,即从组件树的顶部传往底部
- 子组件通过prop的形式从父组件接收数据,props无法直接修改
(一)数据传递
父组件向子组件传递数据
父组件在子组件上声明一个属性,并将数据放在对应属性值上,在子组件中,使用this.props.属性名
访问。
class Parent extends Component {
render() {
return (
<Child myData={'123'}/>
);
}
}
class Child extends Component {
render() {
return (
<div>
子组件
</div>
);
}
componentDidMount(){
console.log(this.props.myData)
}
}
子组件向父组件传递数据
子组件向父组件传递数据需要通过回调函数。
首先,我们在子组件上声明一个属性,属性对应的值是方法。该方法用于接收子组件传入的数据。
在子组件中,我们在传递数据标志触发之后,通过this.props.属性名
的方式触发父组件中获取子组件传入数据的方法,并且将数据传入。
// 父组件
class Parent extends Component {
constructor(){
super()
}
getChildData(val){
console.log(val)
}
render() {
return (
<Child ChildData={this.getChildData} />
);
}
}
// 子组件
class Child extends Component {
constructor(){
super();
this.transferData = this.transferData.bind(this);
}
transferData(){
this.props.ChildData({
name:"传递子组件数据",
content:"子数据数据"
})
}
render() {
return (
<div>
<button onClick={this.transferData}>点击传递数据给父组件</button>
</div>
);
}
}
(二)方法调用
父组件调用子组件的方法
通过refs:在子组件上声明一个ref值,那么在需要调用时,使用this.refs
的方式即可调用子组件的方法。
// 父组件
class Parent extends Component {
constructor(){
super()
this.doChildMethod = this.doChildMethod.bind(this);
}
doChildMethod(){
this.myChild.showMe();
}
render() {
return (
<React.Fragment>
<Child ChildData={this.getChildData} ref="myChild" />
<button onClick={this.doChildMethod}>点击执行子组件的方法</button>
</React.Fragment>
);
}
}
// 子组件
class Child extends Component {
constructor(){
super();
this.showMe = this.showMe.bind(this);
}
showMe(){
console.log('我是子组件,你调用我啦!');
}
render() {
return (
<div>
<div>子组件</div>
</div>
);
}
}
子组件调用父组件的方法
与子组件传值给父组件
// Parent Component
<ChildComponent beforeClick={this.beforeClick} />
beforeClick: function(name) {
if (name === 'vine') {
alert('这是vine写的');
return false;
}
return true;
}
// Children Component
render: function() {
return <button onClick={this.alertMe}>click me </button>;
},
alertMe: function() {
if (!this.props.beforeClick('vine')) {
return false;
}
alert('我被点击了!');
}
(三)特殊情况
因为state异步而得不到props的值
如果有以下情况我们会得不到props的值:
我们在父组件中将state当做初始值传给了子组件。
在传之前,我们在父组件中做了
setState
的操作,该操作为异步操作。在子组件的
componentDidMount
访问传过来的state值,结果为空。
那么,以下方案可以解决这个问题,比如我们要传的数据为myData
,那么以下方式可以得到myData
。这里要注意对myData
长度的判断。
componentWillReceiveProps(nextProps){
if(nextProps.myData!==this.props.myData){
this.setData({
myData:nextProps.myDatas;
})
}
}