在開發(fā)過程中徐紧,經常會遇到父組件和子組件之間相互通信,React子組件和父組件通信包括以下幾個方面:
1,子組件調用父組件的方法
(1)子組件要拿到父組件的屬性并级,需要通過 this.props 方法巴柿。
(2)同樣地,如果子組件想要調用父組件的方法死遭,只需父組件把要被調用的方法以屬性的方式放在子組件上,子組件內部便可以通過“this.props.被調用的方法”這樣的方式來獲取父組件傳過來的方法凯旋。
2呀潭,父組件調用子組件的方法
在 ReactJS 中有個叫 ref 的屬性。這個屬性就像給組件起個引用名字一樣至非,子組件被設置為 ref 之后(比如 ref="xxx")钠署。父組件便可以通過 this.refs.xxx 來獲取到子組件了。
子組件向父組件傳值
例子1:這里如下圖荒椭,用戶郵箱為父谐鼎,綠色框為子。 父組件為用戶輸入的郵箱設好state趣惠,即“{email: ''}”狸棍,同時寫好處理state的函數,即“handleEmail”味悄,這兩個名稱隨
意起草戈;再將函數以props的形式傳到子組件,子組件只需在事件發(fā)生時侍瑟,調用父組件傳過來的函數即可唐片。
效果圖
image.png
// 子類 - Child
import React from 'react';
export default class Child extends React.Component {
render() {
return (
<div>
請輸入郵箱:<input onChange={this.props.handleEmail}/>
</div>
);
}
}
// 父類 - Parent
import React from 'react';
import Child from './Child';
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
email: ' '
}
}
handleEmail = (event) => {
this.setState({
email: event.target.value
});
}
render() {
return (
<div>
<div>用戶郵箱:{this.state.email}</div>
<Child name="email" handleEmail={this.handleEmail}/>
</div>
);
}
}
例子2:有時候往往需要對數據做處理,再傳給父組件涨颜,比如過濾或者自動補全等等费韭,下面的例子對用戶輸入的郵箱做簡單驗證,自動過濾非數字庭瑰、字母和"@."以外的字符星持。
效果圖
image.png
// 子類 - Child
import React from 'react';
export default class Child extends React.Component {
handleVal = () => {
var val = this.refs.emailDom.value;
val = val.replace(/[^0-9|a-z|\@|\.]/ig,"");
this.props.handleEmail(val);
}
render() {
return (
<div>
請輸入郵箱:<input ref="emailDom" onChange={this.handleVal}/>
</div>
);
}
}
// 父類 - Parent
import React from 'react';
import Child from './Child';
export default class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
email: 'ddd'
}
}
handleEmail = (value) => {
this.setState({
email: value
});
}
render() {
return (
<div>
<div>用戶郵箱:{this.state.email}</div>
<Child name="email" handleEmail={this.handleEmail}/>
</div>
);
}
}
例子3:如果還存在孫子組件的情況呢?如下圖弹灭,黑框為父钉汗,綠框為子,紅框為孫鲤屡,要求子孫的數據都傳給爺爺损痰。原理一樣的,只是父要將爺爺對孫子的處理函數直接傳下去酒来。
效果圖
image.png
import React from 'react';
class Grandson extends React.Component {
render() {
return (
<div>性別:
<select onChange={this.props.handleSelect}>
<option value="男">男</option>
<option value="女">女</option>
</select>
</div>
);
}
}
export default class Child extends React.Component {
render() {
return (
<div>
姓名:<input onChange={this.props.handleVal}/>
<Grandson handleSelect={this.props.handleSelect}/>
</div>
);
}
}
import React from 'react';
import Child from './Child';
export default class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
sex: ''
}
}
handleVal = (event) => {
this.setState({
username: event.target.value
});
}
handleSelect = (event) => {
this.setState({
sex: event.target.value
});
}
render() {
return (
<div>
<div>用戶姓名:{this.state.username}</div>
<div>用戶性別:{this.state.sex}</div>
<Child handleVal={this.handleVal} handleSelect={this.handleSelect}/>
</div>
);
}
}
父類調用子類的函數和屬性
// 子類
import React from 'react';
export default class ButtonComment extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
sendSword = () => {
var newCount = this.state.count + 1;
this.setState({
count: this.state.count + 1
});
this.props.getSwordCount();
}
render() {
return (
<button onClick={this.sendSword}>{this.props.buttonName}</button>
);
}
}
// 父類
import ButtonComment from './ButtonComment';
import React from 'react';
export default class ImDaddyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
sendCount: 0
}
}
getSwordCount = () => {
this.setState({sendCount:this.refs.getSwordButton.state.count + 1});
}
sendSword = () => {
this.refs.getSwordButton.sendSword();
}
render() {
return (
<div>
<ButtonComment ref="getSwordButton" getSwordCount={this.getSwordCount} buttonName="兒子送寶刀"/>
<button onClick={this.sendSword}>通過老爸送寶刀</button>
<p>
父子倆共送{this.state.sendCount}把寶刀B础!!
</p>
</div>
);
}
}
效果圖
Snip20171012_1.png
Snip20171012_2.png