useState や useImperativeHandle を使わずに、コンポーネントから別のコンポーネントの関数を実行したい場合に EventEmitter を使うというパターンがあります。
npm install eventemitter3
EventEmitterParentComponent.tsx
import { FC } from 'react';
import { EventEmitterChild1Component } from './EventEmitterChild1Component';
import { EventEmitterChild2Component } from './EventEmitterChild2Component';
import EventEmitter from 'eventemitter3';
export const emitter = new EventEmitter();
export const EventEmitterParentComponent: FC = () => {
return (
<div>
<EventEmitterChild1Component />
<EventEmitterChild2Component />
</div>
);
};
ParentComponent と命名していますが、親子関係は全く関係ありません。
アプリのどこかで
import EventEmitter from 'eventemitter3';
export const emitter = new EventEmitter();
できていればokです。
EventEmitterChild1Component.tsx
import { FC, useEffect } from 'react';
import { emitter } from './EventEmitterParentComponent';
export const EventEmitterChild1Component: FC = () => {
const showAlert = () => {
alert('発火しました!');
};
useEffect(() => {
emitter.on('eventName', showAlert);
// cleanup
return () => {
emitter.off('eventName', showAlert);
};
});
return <div>EventEmitterChild1Component</div>;
};
EventEmitterChild2Component.tsx
import { FC } from 'react';
import { emitter } from './EventEmitterParentComponent';
export const EventEmitterChild2Component: FC = () => {
const handleClick = () => {
emitter.emit('eventName');
};
return (
<div>
<button onClick={handleClick}>ボタンです</button>
</div>
);
};
オプションなど詳しくはこちら
https://qiita.com/twrcd1227/items/e03111230dad483129ab