需求
实现一个轻量级的事件分发中心,不影响现有的框架和数据结构。
实现
准备用zustand
这个状态管理库来做。
安装
首先,安装zustand
库:
bash
npm install zustand
创建一个事件分发中心
然后,创建一个事件分发中心,如eventCenter.js
:
javascript
import create from 'zustand';
const useEventCenter = create((set, get) => ({
events: new Map(),
on: (eventName, callback) => {
const { events } = get();
if (!events.has(eventName)) {
events.set(eventName, []);
}
events.get(eventName).push(callback);
set({ events });
},
off: (eventName, callback) => {
const { events } = get();
if (events.has(eventName)) {
const filteredCallbacks = events.get(eventName).filter(cb => cb !== callback);
events.set(eventName, filteredCallbacks);
set({ events });
}
},
emit: (eventName, ...args) => {
const { events } = get();
if (events.has(eventName)) {
events.get(eventName).forEach(callback => callback(...args));
}
},
}));
export default useEventCenter;
使用zustand
创建了一个存储,包含events
(用于存储事件回调的Map对象)以及三个方法:on
(用于订阅事件)、off
(用于取消订阅事件)和emit
(用于触发事件)。
在组件中使用useEventCenter
进行事件订阅和触发。例如,以下是一个简单的Parent
和Child
组件示例:
Parent.js
:
javascript
import React, { useEffect } from 'react';
import useEventCenter from './eventCenter';
import Child from './Child';
const Parent = () => {
const { on, off, emit } = useEventCenter();
useEffect(() => {
const handleButtonClick = () => {
console.log('Button clicked in Child component');
};
on('buttonClick', handleButtonClick);
return () => {
off('buttonClick', handleButtonClick);
};
}, [on, off]);
return (
<div>
<h1>Parent Component</h1>
<Child onButtonClick={() => emit('buttonClick')} />
</div>
);
};
export default Parent;
Child.js
:
javascript
import React from 'react';
const Child = ({ onButtonClick }) => {
return (
<div>
<h2>Child Component</h2>
<button onClick={onButtonClick}>Click me</button>
</div>
);
};
export default Child;
多个组件之间的事件通信。
首先,创建一个新的组件Sibling.js
,它将与Child.js
并列:
Sibling.js
:
javascript
import React, { useEffect } from 'react';
import useEventCenter from './eventCenter';
const Sibling = () => {
const { on, off } = useEventCenter();
useEffect(() => {
const handleButtonClick = () => {
console.log('Button clicked in Sibling component');
};
on('buttonClick', handleButtonClick);
return () => {
off('buttonClick', handleButtonClick);
};
}, [on, off]);
return (
<div>
<h2>Sibling Component</h2>
</div>
);
};
export default Sibling;
在Sibling.js
组件中,订阅了名为buttonClick
的事件,以便在Child.js
组件中触发该事件时收到通知。
现在,需要更新Parent.js
组件以包含Sibling.js
组件:
Parent.js
:
javascript
import React from 'react';
import Child from './Child';
import Sibling from './Sibling';
const Parent = () => {
return (
<div>
<h1>Parent Component</h1>
<Child />
<Sibling />
</div>
);
};
export default Parent;