要在 Reply 組件中通過?statusChangeEvent
?發送狀態值,并在 Select 組件中接收這個狀態值?status
,你可以按照以下步驟實現:
//Event.jsimport EventEmitter from 'events';export const statusChangeEvent = new EventEmitter();// 工單狀態切換事件
1. 在 Reply 組件中發送狀態值
你已經正確地在 Reply 組件中設置了事件發射:
// Reply.jsx
import { statusChangeEvent } from './Event';const Reply = () => {const [status, setStatus] = useState('');const changeStatus = useCallback(status => {setStatus(status);statusChangeEvent.emit('status-changedValue', status);}, []);return (// 你的組件內容<button onClick={() => changeStatus('new-status')}>更改狀態</button>);
};
2. 在 Select 組件中接收狀態值
// Select.jsx
import { useEffect, useState } from 'react';
import { statusChangeEvent } from './Event';const Select = () => {const [status, setStatus] = useState('');useEffect(() => {// 定義事件監聽器const handleStatusChange = (newStatus) => {setStatus(newStatus);};// 添加事件監聽statusChangeEvent.on('status-changedValue', handleStatusChange);// 組件卸載時移除監聽return () => {statusChangeEvent.off('status-changedValue', handleStatusChange);};}, []);return (<div><p>當前狀態: {status}</p>{/* 其他組件內容 */}</div>);
};
3. 優化方案(推薦)
雖然 EventEmitter 可以工作,但在 React 中更推薦使用 Context 或狀態管理庫(如 Redux)來處理跨組件狀態共享。以下是使用 Context 的替代方案:
創建狀態上下文
// StatusContext.js
import { createContext, useContext, useState } from 'react';const StatusContext = createContext();export const StatusProvider = ({ children }) => {const [status, setStatus] = useState('');return (<StatusContext.Provider value={{ status, setStatus }}>{children}</StatusContext.Provider>);
};export const useStatus = () => useContext(StatusContext);
在 Reply 組件中使用
// Reply.jsx
import { useStatus } from './StatusContext';const Reply = () => {const { setStatus } = useStatus();const changeStatus = useCallback(status => {setStatus(status);}, [setStatus]);return (<button onClick={() => changeStatus('new-status')}>更改狀態</button>);
};
在 Select 組件中使用
// Select.jsx
import { useStatus } from './StatusContext';const Select = () => {const { status } = useStatus();return (<div><p>當前狀態: {status}</p></div>);
};
在應用頂層包裹 Provider
// App.js
import { StatusProvider } from './StatusContext';function App() {return (<StatusProvider><Reply /><Select /></StatusProvider>);
}
注意事項
-
EventEmitter 方案:
-
適合非父子組件間的通信
-
記得在組件卸載時移除監聽器
-
可能導致難以追蹤的數據流
-
-
Context 方案:
-
React 推薦的方式
-
更易于維護和調試
-
當狀態變化時,所有使用該狀態的組件都會重新渲染
-
-
性能考慮:
-
如果狀態更新頻繁,考慮使用 useMemo 或 React.memo 優化性能
-
對于復雜應用,Redux 或 Zustand 可能是更好的選擇
-
選擇哪種方案取決于你的應用復雜度和組件結構。對于簡單場景,EventEmitter 足夠;對于更復雜的應用,推薦使用 Context 或狀態管理庫。