目次
親コンポーネントは子コンポーネントのデータとメソッドを取得します
コンテキストを使用してレベル間のコンポーネント通信を実装する
EventEmitter を使用して無関係なコンポーネント間の通信を実装する
親コンポーネントと子コンポーネント間の通信
親コンポーネントがデータとメソッドを子コンポーネントに渡す
親コンポーネントはデータとメソッドを子コンポーネントに渡すことができ、子コンポーネントは props を通じてそれらを取得します。
親コンポーネント:
import React from "react";
import Child from "./Child";
export default class Demo extends React.Component {
constructor(props) {
super(props)
this.state = {
value: 0
}
this.changeValue = this.changeValue.bind(this)
}
changeValue() {
this.setState({
value: this.state.value + 1
}, () => {
console.log('changeValue 方法执行了 value: ', this.state.value)
})
}
render() {
const value = this.state.value
return (
<div>
<h1>父组件</h1>
<p>value: {value}</p>
<Child
// 向子组件传递数据
value={value}
// 向子组件传递方法
changeValue={this.changeValue}
></Child>
</div>
)
}
}
サブアセンブリ:
import React from "react";
export default class Child extends React.Component {
constructor(props) {
super(props)
}
dealClidk() {
// 子组件触发父组件的方法执行
this.props.changeValue()
}
render() {
return (
<div>
<h1>子组件</h1>
{/* 子组件通过props获取父组件传递的数据 */}
<p>value:{this.props.value}</p>
<button onClick={this.dealClidk.bind(this)}>点击</button>
</div>
)
}
}
子コンポーネントのボタンをクリックすると、親コンポーネントのメソッドがトリガーされて、親コンポーネントのプロパティ値を変更できます。
親コンポーネントは子コンポーネントのデータとメソッドを取得します
親コンポーネントは、ref を通じて子コンポーネントのデータとメソッドを取得できます。
親コンポーネント:
import React from "react";
import Child from "./Child";
export default class Demo extends React.Component {
constructor(props) {
super(props)
this.ChildRef = React.createRef()
}
dealClidk() {
if (this.ChildRef && this.ChildRef.current) {
// 父组件触发子组件方法的执行
this.ChildRef.current.changeValue()
}
}
getData() {
if (this.ChildRef && this.ChildRef.current) {
// 父组件获取子组件中state的值
const childData = this.ChildRef.current.state.data
console.log('获取子组件的数据 childData: ', childData)
}
}
render() {
return (
<div>
<h1>父组件</h1>
<button onClick={this.dealClidk.bind(this)}>点击</button>
<button onClick={this.getData.bind(this)}>获取</button>
<Child ref={this.ChildRef}></Child>
</div>
)
}
}
サブアセンブリ:
import React from "react";
export default class Child extends React.Component {
constructor(props) {
super(props)
this.state = {
data: 0
}
this.changeValue = this.changeValue.bind(this)
}
changeValue() {
this.setState({
data: this.state.data + 1
}, () => {
console.log('changeValue 方法执行了 data: ', this.state.data)
})
}
render() {
const data = this.state.data
return (
<div>
<h1>子组件</h1>
<p>value:{data}</p>
</div>
)
}
}
クロスレベルコンポーネント間の通信
小道具を使用してレベル間のコンポーネント通信を実装する
クロスレベルコンポーネント通信を実現するためにプロップを使用する方法も 2 つあります。
レベルごとの直接転送
親コンポーネント:
import React from "react";
import Child from "./Child";
export default class Demo extends React.Component {
constructor(props) {
super(props)
this.state = {
value: 0,
value2: '张三'
}
this.changeValue = this.changeValue.bind(this)
}
changeValue() {
this.setState({
value: this.state.value + 1
}, () => {
console.log('changeValue 方法执行了 value: ', this.state.value)
})
}
render() {
const { value, value2 } = this.state
return (
<div>
<h1>父组件</h1>
<p>value: {value}</p>
<p>value2: {value2}</p>
<button onClick={this.changeValue}>点击</button>
<Child
value={value}
value2={value2}
></Child>
</div>
)
}
}
サブアセンブリ:
import React from "react";
import GrandSon from "./GrandSon";
export default class Child extends React.Component {
render() {
const { value, value2 } = this.props
return (
<div>
<h1>子组件</h1>
<GrandSon
// 子组件将数据继续向下传递
value={value}
value2={value2}
></GrandSon>
</div>
)
}
}
孫子のコンポーネント
import React from "react";
export default class GrandSon extends React.Component {
constructor(props) {
super(props)
}
render() {
const { value, value2 } = this.props
return (
<div>
<h1>孙子组件</h1>
<p>value: {value}</p>
<p>value2: {value2}</p>
</div>
)
}
}
この方法は、少量のデータを転送する場合に適しており、1つずつ転送できますが、転送するデータが多い場合、この方法を使用するとコードの重複が発生しやすくなります。{...this.props} を使用してパッケージ化して渡すことができます。親コンポーネントによって渡されるデータの量に関係なく、子コンポーネントはすべてのデータをパッケージ化して孫コンポーネントに渡し、孫コンポーネントは引き続き this.props を使用してデータを取得できます。
サブコンポーネントの配信方法を変更してみましょう。
import React from "react";
import GrandSon from "./GrandSon";
export default class Child extends React.Component {
render() {
return (
<div>
<h1>子组件</h1>
<GrandSon
// 子组件将数据继续向下传递
{...this.props}
></GrandSon>
</div>
)
}
}
同様の効果が得られていることがわかります。
コンテキストを使用してレベル間のコンポーネント通信を実装する
コンテキストを使用してレベル間でデータを転送するには、次の手順が必要です。
1. React.createContext() を通じてコンテキスト インスタンスを作成します
import React from "react";
const DemoContext = React.createContext()
export default DemoContext;
2. プロバイダーを介してプロデューサーを作成します。プロバイダーには、渡す必要があるデータをパッケージ化するために使用できる value 属性があります。
import React from "react";
import Child from "./Child";
import DemoContext from './DemoContext'
export default class Demo extends React.Component {
constructor(props) {
super(props)
this.state = {
value: 0,
value2: '张三'
}
this.changeValue = this.changeValue.bind(this)
}
changeValue() {
this.setState({
value: this.state.value + 1
}, () => {
console.log('changeValue 方法执行了 value: ', this.state.value)
})
}
render() {
const { value, value2 } = this.state
return (
<div>
<h1>父组件</h1>
<p>value: {value}</p>
<p>value2: {value2}</p>
<button onClick={this.changeValue}>点击</button>
<DemoContext.Provider value={
{
value: value,
value2: value2
}}>
<Child></Child>
</DemoContext.Provider>
</div>
)
}
}
3. Consumer を通じて渡されたデータを受け取るコンシューマを作成します。
import React from "react";
import DemoContext from "./DemoContext";
export default class GrandSon extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<h1>孙子组件</h1>
<DemoContext.Consumer>
{/* Consumer中需要使用函数 */}
{
(value) => {
return (
<div>
<p>value: {value.value}</p>
<p>value2: {value.value2}</p>
</div>
)
}
}
</DemoContext.Consumer>
</div>
)
}
}
中間コンポーネント:
import React from "react";
import GrandSon from "./GrandSon";
export default class Child extends React.Component {
render() {
return (
<div>
<h1>子组件</h1>
<GrandSon></GrandSon>
</div>
)
}
}
状態管理を使用してレベル間のコンポーネント通信を実装する
以前のブログを参照してください: React-redux グローバル状態管理
無関係なコンポーネント間の通信
EventEmitter を使用して無関係なコンポーネント間の通信を実装する
EventEmitter を使用する手順;
1. イベントライブラリをインストールする
npm install events
2. EventEmitterのインスタンスを作成する
import React from "react";
import { EventEmitter } from "events";
// 创建EventEmitter实例
const DemoEvent = new EventEmitter()
export default DemoEvent;
3. リリースイベント
Emit("イベント名", パラメータ) を使用してイベントを公開します
import React from "react";
import DemoEvent from './DemoEvent'
export default class GrandSon extends React.Component {
constructor(props) {
super(props)
this.state = {
value: 0
}
this.changeValue = this.changeValue.bind(this)
}
changeValue() {
this.setState({
value: this.state.value + 1
}, () => {
console.log('changeValue 方法执行了 value: ', this.state.value)
// 发送一个事件
DemoEvent.emit('sendData', this.state.value)
})
}
render() {
return (
<div>
<h1>孙子组件 GrandSon</h1>
<p>{this.state.value}</p>
<button onClick={this.changeValue}>点击</button>
</div>
)
}
}
4. イベントを購読する
イベントをサブスクライブするには、addListener("イベント名", callback function) または on("event name", callback function) を使用できます。
5. サブスクリプションをキャンセルする
購読を解除するには、removeListener("イベント名", コールバック関数) または off("イベント名", コールバック関数) を使用できます。
import React from "react";
import DemoEvent from './DemoEvent'
export default class GrandSon2 extends React.Component {
constructor(props) {
super(props)
this.state = {
value: 0
}
this.receiveData = this.receiveData.bind(this)
}
componentDidMount() {
// 订阅事件
DemoEvent.addListener('sendData', this.receiveData)
}
receiveData(data) {
console.log('接收的数据 data: ', data)
this.setState({
value: data
})
}
componentWillUnmount() {
// 取消订阅
DemoEvent.removeListener(this.receiveData)
}
render() {
return (
<div>
<h1>孙子组件 GrandSon2</h1>
<p>{this.state.value}</p>
</div>
)
}
}
状態管理を使用して独立したコンポーネント間で通信する
以前のブログを参照してください: React-redux グローバル状態管理
補足: EventEmitter を自分で実装する
つづく