「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」。
关于 React 的组件间通讯,网上有很多组件间通讯的文章。
父子组件间直接传事件,然后提升处理就可以。
父子孙曾孙之类的,也可以把事件一层层地传进去,这样虽然繁琐,但是感觉结构清晰。
再就是事件总线(Event Bus)的方式。
无直接关系相对独立的组件间,只能采用事件总线的方式。
事件总线,感觉就是针对全局的事件监听和事件触发。
事件总线这个,本来是一个很简单的技术点。
为了下次遇到同样的问题减少搜索,还是自己整理了一个小例子。
在组件1中注册事件总线,在组件2中触发事件,组件1监听到事件被触发后作出响应处理。
相关代码:helloreact/eventbus at main · bettersun/helloreact · GitHub
-
create-react-app 创建 React 工程。
npx create-react-app eventbus -
事件总线相关的 js。
event.js
```javascript import { EventEmitter } from 'events'; // new一个全局的EventEmitter对象 const eventEmiter = new EventEmitter(); // 组件间通讯的事件 const eventHello = "hello"; // 注册事件监听 export function addListenerHello(handler) { eventEmiter.on(eventHello, handler); } // 触发事件 export function doHello(args) { eventEmiter.emit(eventHello, args); } ```导入 events 里的 EventEmitter。
在 event.js 里创建一个全局的 EventEmitter 对象。
定义(触发和监听的)事件名称,然后定义一个用来注册事件监听的函数和一个触发事件的函数。 -
组件1
import { useState, useEffect } from "react"; import { addListenerHello } from './event'; function HelloOne() { const [message, setMessage] = useState("Hello"); useEffect( () => { // 注册事件监听,把事件触发时要调用的处理函数传递过去。 // 运行一次即可 addListenerHello(helloHandler); }, [] ) // 组件间通讯事件触发时的处理。 function helloHandler(args) { setMessage("Hello, " + args + "!") } return ( <div> {message} </div> ); } export default HelloOne;注册事件监听,把事件触发时要调用的处理函数传递过去。
运行一次即可。 -
组件2
import { useState } from "react"; import { doHello } from './event'; function HelloTwo() { const [message, setMessage] = useState(""); function hello() { // 触发组件间通讯的事件,传递参数。 doHello("world"); setMessage("I said hello."); } return ( <div> <button onClick={hello}>say hello</button> <br /> {message} </div> ); }sd export default HelloTwo;组件2中的动作触发事件,组件1会监听到事件的触发后进行对应的处理。
-
App.js
import HelloOne from './HelloOne'; import HelloTwo from './HelloTwo'; import './App.css'; function App() { return ( <div className="App"> <div className={'column1'}> <HelloOne></HelloOne> </div> <div className={'column2'}> <HelloTwo></HelloTwo> </div> </div> ); } export default App;App.js 中放置组件1和组件2,二者相对独立。
-
效果: