React のコンポーネント間の通信 (親子コンポーネント、レベル間コンポーネント、無関係なコンポーネント)

目次

親コンポーネントと子コンポーネント間の通信

親コンポーネントがデータとメソッドを子コンポーネントに渡す

親コンポーネントは子コンポーネントのデータとメソッドを取得します

クロスレベルコンポーネント間の通信

小道具を使用してレベル間のコンポーネント通信を実装する

コンテキストを使用してレベル間のコンポーネント通信を実装する

状態管理を使用してレベル間のコンポーネント通信を実装する

無関係なコンポーネント間の通信

EventEmitter を使用して無関係なコンポーネント間の通信を実装する

 状態管理を使用して独立したコンポーネント間で通信する

補足: 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 を自分で実装する

つづく

おすすめ

転載: blog.csdn.net/Celester_best/article/details/126218290