需求
实现一个轻量级的事件分发中心,不影响现有的框架和数据结构。
实现
准备用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;