我们都知道在React中,父子组件通信可以通过props和state,但是非父子组件通信怎么办呢?我们可以使用EventBus来实现非父子组件通信。EventBus是一个事件总线,我们可以使用EventBus来发布事件,然后通过订阅事件来接收事件。我们可以使用Context
来实现React中非父子组件通信。当然我们还可以使用第三方库来实现非父子组件通信,比如redux
。这里我们使用EventBus
来实现非父子组件通信。
创建EventBus.js文件
我们先创建一个event-bus.js
文件,如下所示:
import { HYEventBus } from "hy-event-store"
const eventBus = new HYEventBus()
export default eventBus
我们在这里使用了hy-event-store
库来实现EventBus,你也可以使用其他第三方库或者自己实现。
使用EventBus来实现非父子组件通信
我们先看一个例子:
import React,{Component} from "react";
import Home from './Home'
import eventBus from "./utils/event-bus";
export class App extends Component{
constructor(){
super()
this.state = {
name:"",
age:0,
height:0
}
}
componentDidMount(){
// eventBus.on("bannerPrev",(name,age,height)=>{
// console.log("app中监听到的bannerPrev",name,age,height)
// this.setState({name,age,height})
// })
eventBus.on("bannerPrev",this.bannerPrevClick,this)
eventBus.on("bannerNext",this.bannerNextClick,this)
}
bannerPrevClick(name,age,height){
console.log("app中监听到bannerPrev",name,age,height)
this.setState({name,age,height})
}
bannerNextClick(info){
console.log("app中监听到bannerNext",info)
}
componentWillUnmount(){
eventBus.off("bannerPrev",this.bannerPrevClick)
}
render(){
const { name,age,height } = this.state
return ( <div>
<h2>App Component:{name}-{age}-{height}</h2>
<Home></Home>
</div>)
}
}
export default App
在上面的代码中,我们在App
组件中使用eventBus.on()
方法来订阅事件。当Home
组件触发bannerPrev
或bannerNext
事件时,我们可以在App
组件中接收到这些事件并执行相应的操作。这里我们要注意的一点是,我们在componentWillUnmount()
方法中使用了eventBus.off()
方法来取消订阅事件,这样可以避免内存泄漏。
Home组件
下面是我们的Home
组件的实现:
import React,{Component} from "react";
import HomeBanner from './HomeBanner'
export class Home extends Component{
render(){
return (
<div>
<h2>Home Component</h2>
<HomeBanner></HomeBanner>
</div>
)
}
}
export default Home
以上代码中,我们只是简单地渲染了HomeBanner
组件。其中又包含了HomeBanner
组件。接下来我们来看一下HomeBanner
组件的实现。
HomeBanner组件
import React,{Component} from "react";
import eventBus from "./utils/event-bus";
export class HomeBanner extends Component{
prevClick(){
console.log("上一个")
eventBus.emit("bannerPrev","why",18,1.88)
}
nextClick(){
console.log("下一个")
eventBus.emit("bannerNext",{nickname:'kobe',level:99})
}
render(){
return (
<div>
<h2>HomeBanner</h2>
<button onClick={e => this.prevClick()}>上一个</button>
<button onClick={e => this.nextClick()}>下一个</button>
</div>
)
}
}
export default HomeBanner
由于这里我们需要在HomeBanner
组件中触发事件,所以我们在HomeBanner
组件中使用了eventBus.emit()
方法来触发事件。这样我们就可以在HomeBanner
组件中调用App
组件中的方法,并且在App
组件中接收到这些事件并执行相应的操作。下面附上页面效果:
感谢阅读
of course like your web site but you need to test the spelling on quite a few of your posts. A number of them are rife with spelling problems and I in finding it very troublesome to inform the reality nevertheless I will surely come again again.
新年快乐!
十天看一部剧,还可以吧
@梦不见的梦 行,谢谢提醒,我优化一下
网站的速度有待提升,每次打开都要转半天还进不来呢
@React实战爱彼迎项目(二) - 程序员鸡皮 哪里有问题了,报错了吗?
@Teacher Du 那是怕你们毕不了业,我大学那会儿给小礼品
我们大学那会,献血还给学分~
@ab 我想去学网安,比如网警,但分也贼高😕
@夜 加油,你一样也可以成为程序员的,需要学习资料可以V我