事件总栈
前端开发都会遇到一个老生常谈的场景,如下:
多组件、父子组件、孙子爷爷太爷爷组件如何进行互相的数据交互?
TL;DR
前言
所谓事件总栈就是一个集中管理和发布订阅的函数,通俗的讲就是发布订阅模式,接下来介绍一个react中个人用的比较多的三方库。如果想了解什么是发布订阅模式可以看我的这篇文章
useEventEmitter
拿React下Ahooks库提供的useEventEmitter
来说:
使用方式
组件A(父)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| export const MainView: React.FC = () => {
const ctx$ = useEventEmitter() ctx$.useSubscription((opt) => { const {type, payload} = opt if (type === 'jump') { console.log(`${payload.name} jump`) return } if (type === 'pay') { console.log(`pay ${payload.currency}`) return } ... })
return ( <> <Child1 ctx={ctx$}></Child> <Child2 ctx={ctx$}></Child> </> ) }
|
其他组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| export const Child1: React.FC = ({ctx}) => {
const handleBtnClick = () =>{ ctx.emit({ type: 'jump', payload: { name: 'Mike' } }) } return ( <> <Button>Press Me</Button> </> ) }
|
如上
当然,在子组件和孙子组件中也可以直接坚挺emit事件,只需要在写上ctx.useSubscription
即可,例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| export const Child2: React.FC = ({ctx}) => {
const handleBtnClick = () =>{ ctx.emit({ type: 'pay', payload: { currency: 20.22 } }) }
ctx$.useSubscription((opt) => { const {type, payload} = opt if (type === 'jump') { console.log(`${payload.name} jump`) return } }
return ( <> <Button>Press Me</Button> </> ) }
|
不过在使用的时候注意控制好订阅者,不要滥用,以免出现重复监听的问题。「到时追悔莫及,debug一百年」。
👋 ;
前端, 技术分享 — 2025年4月20日