React学习笔记23-非父子通信(订阅发布模式)
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.降低父子组件之前的耦合度,有利于代码维护

浙公网安备 33010602011771号