一、父传子
父传子的通信方法
通过props传递
代码
略
二、子传父
子传父的通信方法
- 父组件编写事件处理程序
- 父组件通过props传递事件处理程序到子组件
- 子组件调用props传递的方法(在生命周期带调用或通过事件监听)
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>Document</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class ChildComponent extends React.Component {
componentDidMount() {
const data = [
{ id: 1, name: 'zhangsan' },
{ id: 2, name: 'lisi' }
]
const { getData } = this.props
// 3.子组件绑定props传递的方法,并使用bind传参(通过生命周期)
setTimeout(() => {
getData(data)
}, 2000)
}
render() {
const { getData } = this.props
const data = [
{ id: 1, name: 'a' },
{ id: 2, name: 'b' }
]
// 3.子组件绑定props传递的方法,并使用bind传参(通过监听器)
return <button onClick={getData.bind(this, data)}>child</button>
}
}
class ParentComponent extends React.Component {
// 1.父组件编写事件处理程序
getData = (data) => {
console.log(data)
}
render() {
// 2.父组件通过props传递事件处理程序
return <ChildComponent getData={this.getData} />
}
}
ReactDOM.render(<ParentComponent />, document.getElementById('root'))
</script>
</body>
</html>
三、跨级组件
跨级组件通信的方式
- props
- context
四、兄弟组件
兄弟组件通信的方式
- events
- 子传父传子
- context
代码
App.js(父组件)
import "./App.css";
import React from "react";
import Brother2 from "./components/brother2";
import Brother1 from "./components/brother1";
import Child1 from "./components/child1";
import Child2 from "./components/child2";
import Consumer1 from "./components/consumer1";
import Consumer2 from "./components/consumer2";
import { DataContext } from "./components/dataContext";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
transferedData: "parent data",
consumerData: "default context",
};
}
handleChildClick = (data) => {
this.setState({ transferedData: data });
};
handleConsumerClick = (data) => {
this.setState({ consumerData: data });
};
render() {
return (
<div>
<ul>
<li>
<h1>1.兄弟组件通信--events</h1>
<h3>Brother2<->Brother1</h3>
<Brother1 />
<Brother2 />
</li>
<li>
<h1>2.兄弟组件通信--子传父传子</h1>
<h3>Child1-App-Child2</h3>
<h3>{this.state.transferedData}</h3>
<Child1 onChildClick={this.handleChildClick} />
<Child2 transferedData={this.state.transferedData} />
</li>
<li>
<h1>3.兄弟组件通信--context</h1>
<h3>Consumer1-App-Consumer2</h3>
<DataContext.Provider value="no data">
<p>data:{this.state.consumerData}</p>
<Consumer1 onConsumerClick={this.handleConsumerClick} />
<Consumer2 consumerData={this.state.consumerData} />
</DataContext.Provider>
</li>
<li>
……
{/* <h1>4.兄弟组件通信--利用组合关系</h1>
<h3></h3> */}
</li>
</ul>
</div>
);
}
}
export default App;
兄弟组件第一组
brother1.js
import React, { Component } from "react";
import eventsEmitter from "./event";
export default class Home extends Component {
constructor(props) {
super(props);
this.state = { text: "brother1" };
}
handleClick = () => {
eventsEmitter.emit("brother1Say", "brother1 message");
};
componentDidMount() {
eventsEmitter.on("brother2Say", (data) => {
console.log("brother1 listen to brother2");
this.setState({ text: data });
});
}
componentWillUnmount() {
eventsEmitter.removeAllListeners("brother2Say");
}
render() {
return (
<div className="brother1">
<button onClick={this.handleClick}>brother1</button>
<h2>{this.state.text}</h2>
</div>
);
}
}
brother2.js
import React, { Component } from "react";
import eventsEmitter from "./event";
export default class About extends Component {
constructor(props) {
super(props);
this.state = { text: "brother2" };
}
handleClick = () => {
eventsEmitter.emit("brother2Say", "brother2 message");
};
componentDidMount() {
eventsEmitter.on("brother1Say", (data) => {
console.log("brother2 listen to brother1");
this.setState({ text: data });
});
}
componentWillUnmount() {
eventsEmitter.removeAllListeners("brother1Say");
}
render() {
return (
<div className="brother2">
<button onClick={this.handleClick}>brother2</button>
<h2>{this.state.text}</h2>
</div>
);
}
}
兄弟组件第二组
child1.js
import React, { Component } from "react";
export default class Child1 extends Component {
render() {
const onChildClick = this.props.onChildClick;
return (
<div className="child">
<button onClick={onChildClick.bind(this, "Child1 data")}>Child1</button>
</div>
);
}
}
child2.js
import React, { Component } from "react";
export default class Child1 extends Component {
render() {
return (
<div className="child">
Child2:{this.props.transferedData || "Child2"}
</div>
);
}
}
兄弟组件第三组
consumer1.js
import React, { Component } from "react";
import { DataContext } from "./dataContext";
export default class Consumer1 extends Component {
static contextType = DataContext;
render() {
return (
<div className="child">
<button
onClick={this.props.onConsumerClick.bind(this, "consumer1 data")}
>
consumer1
</button>
<span>data:{this.context}</span>
</div>
);
}
}
consumer2.js
import React, { Component } from "react";
import { DataContext } from "./dataContext";
export default class Consumer1 extends Component {
static contextType = DataContext;
render() {
return (
<div className="child">
<button>consumer2</button>
<span>data:{this.props.consumerData}</span>
</div>
);
}
}
五、非嵌套组件
非嵌套组件通信的方式
- events