React学习笔记23-非父子通信(订阅发布模式)

发布时间 2023-11-08 11:00:29作者: SadicZhou

1.订阅发布模式进行兄弟组件通信的案例

 1.构建一个调度中心

var bus = {
    list: [],
    //订阅
    subscribe(callback) {
        this.list.push(callback)
        console.log(this.list)
    },
    //发布
    publish(name, text) {
        //遍历所有list,将回调函数执行
        this.list.forEach((item, index) => {
            if (item && item.name === name)
                item.fun(text)
        })
    }
}

2.书写业务代码

import React, { Component } from 'react'
import axios from 'axios'
var bus = {
    list: [],
    //订阅
    subscribe(callback) {
        this.list.push(callback)
        console.log(this.list)
    },
    //发布
    publish(name, text) {
        //遍历所有list,将回调函数执行
        this.list.forEach((item, index) => {
            if (item && item.name === name)
                item.fun(text)
        })
    }
}
export default class App extends Component {
    constructor() {
        super()
        this.state = {
            filmList: [],
        }
        axios.get('http://localhost:3000/filmlist.json').then(res => {
            console.log(res.data.data.films)
            this.setState({
                filmList: res.data.data.films
            })
        })
    }
    render() {
        return (
            <div>
                {this.state.filmList.map(item => {
                    return (
                        <FilmItem {...item} key={item.filmId}></FilmItem>
                    )
                })}
                <FilmDetail></FilmDetail>
            </div>
        )
    }
}
/* 受控组件 */
class FilmItem extends Component {
    //发布者
    render() {
        return (
            <div style={{ overflow: 'hidden', padding: '10px' }} onClick={
                () => {
                    //发布
                    bus.publish("getDetail", this.props.synopsis)
                }
            }>
                <img style={{ width: '100px', float: "left" }} src={this.props.poster} alt="" />
                <h4>{this.props.name}</h4>
                <h5>观众评分:{this.props.grade}</h5>
            </div>
        )
    }
}

class FilmDetail extends Component {
    constructor() {
        super()
        this.state = {
            detail: ""
        }
        //订阅
        bus.subscribe({
            name: "getDetail", fun: (value) => {
                this.setState({
                    detail: value
                })
            }
        })
    }
    render() {
        return (
            <div style={{ position: 'fixed', right: '0', top: '100px', background: 'yellow', width: "200px", padding: "10px" }}
            >{this.state.detail}</div>
        )
    }
}

可以看到FilmItem组件是发布者,负责发布电影的详情信息。在发布时传入了一个方法名和详情信息。

FilmDetail组件是订阅者,向调度中心传入了一个对象包含了方法名和方法体。

订阅发布模式比起中间人模式的好处

1.可以进行局部刷新。而不需要每次都通过父组件的setState来将所有的子组件都刷新。

2.降低父子组件之前的耦合度,有利于代码维护