在开发过程中,经常会遇到父组件和子组件之间相互通信,React子组件和父组件通信包括以下几个方面:

1,子组件调用父组件的方法
(1)子组件要拿到父组件的属性,需要通过 ​​​this.props​​​ 方法。
(2)同样地,如果子组件想要调用父组件的方法,只需父组件把要被调用的方法以属性的方式放在子组件上,
子组件内部便可以通过​​​“this.props.被调用的方法​​”这样的方式来获取父组件传过来的方法。

2,父组件调用子组件的方法
在 ReactJS 中有个叫 ref 的属性。这个属性就像给组件起个引用名字一样,子组件被设置为 ref 之后(比如 ref=“xxx”)。父组件便可以通过 ​​​this.refs.xxx​​ 来获取到子组件了。

子组件向父组件传值

  • 子组件通过this.props.fun 使用父组件的方法
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 实例</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">


class Child extends React.Component {

render() {
return (
<div>
请输入邮箱:<input onChange={this.props.handleEmail}/>
</div>
);
}
}



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>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('example')
);


</script>

</body>
</html>

子组件部分处理

  • 有时候往往需要对数据做处理,再传给父组件,比如过滤或者自动补全等等,下面的例子对用户输入的邮箱做简单验证,自动过滤非数字、字母和"@."以外的字符。
    效果图
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 实例</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">
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
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>
);
}
}

ReactDOM.render(
<Parent />,
document.getElementById('example')
);

</script>

</body>
</html>

多级的传递

  • 如果还存在孙子组件的情况呢?如下图,黑框为父,绿框为子,红框为孙,要求子孙的数据都传给爷爷。原理一样的,只是父要将爷爷对孙子的处理函数直接传下去。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 实例</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">

class Grandson extends React.Component {
render() {
return (
<div>性别:
<select onChange={this.props.handleSelect}>
<option value="男">男</option>
<option value="女">女</option>
</select>
</div>
);
}
}

class Child extends React.Component {

render() {
return (
<div>
姓名:<input onChange={this.props.handleVal}/>
<Grandson handleSelect={this.props.handleSelect}/>
</div>
);
}
}

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>
);
}
}

ReactDOM.render(
<Parent />,
document.getElementById('example')
);


</script>

</body>
</html>

父类调用子类的函数和属性

  • 通过refs获取
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 实例</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">
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>
);
}
}
// 父类
class ImDaddyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
sendCount: 0
}



}


getSwordCount = () => {
this.setState({sendCount:this.refs.getSwordButton.state.count + 1});
}

sendSword = () => {
console.log(this.refs);

this.refs.getSwordButton.sendSword();
}

render() {

return (
<div>
<ButtonComment ref="getSwordButton" getSwordCount={this.getSwordCount} buttonName="儿子送宝刀"/>
<button onClick={this.sendSword}>通过老爸送宝刀</button>
<p>
父子俩共送{this.state.sendCount}把宝刀!!!
</p>
</div>
);
}
}


ReactDOM.render(
<ImDaddyComponent />,
document.getElementById('example')
);

</script>

</body>
</html>

参考