React 16.x独立组件通信:PubSub失效后的可行解决方案
Hey there! Let's tackle this PubSub issue in React 16.x first, then walk through other reliable component communication methods you can use.
First, let's make sure you're using the library correctly—small oversights often cause this kind of problem.
Double-check your PubSub package
The most common library for this use case ispubsub-js. Make sure you've installed it first:npm install pubsub-js # or yarn add pubsub-jsThen import it correctly in your components:
import PubSub from 'pubsub-js';Subscribe at the right time (and clean up!)
In React 16.x, for class components, subscribe incomponentDidMount(so the component is fully mounted before listening) and always unsubscribe incomponentWillUnmountto avoid memory leaks. For function components, useuseEffectwith a cleanup function.Example for class components:
class ReceiverComponent extends React.Component { state = { receivedData: null }; componentDidMount() { // Save the subscription ID to unsubscribe later this.subId = PubSub.subscribe('DATA_UPDATED', (topic, payload) => { this.setState({ receivedData: payload }); }); } componentWillUnmount() { PubSub.unsubscribe(this.subId); } render() { return <div>Received: {this.state.receivedData}</div>; } }Example for function components:
import { useEffect, useState } from 'react'; import PubSub from 'pubsub-js'; function ReceiverComponent() { const [receivedData, setReceivedData] = useState(null); useEffect(() => { const subId = PubSub.subscribe('DATA_UPDATED', (_, payload) => { setReceivedData(payload); }); // Cleanup: unsubscribe when component unmounts return () => PubSub.unsubscribe(subId); }, []); return <div>Received: {receivedData}</div>; }Publish only when subscribers are ready
Don't publish data incomponentWillMount—the receiver might not have subscribed yet. Instead, publish on user actions (like button clicks) or incomponentDidMountof the sender (if you need to send data on mount).Example sender component:
function SenderComponent() { const sendData = () => { PubSub.publish('DATA_UPDATED', 'Hello from Sender!'); }; return <button onClick={sendData}>Send Data via PubSub</button>; }Verify your topic names
A super common mistake is typos or case mismatches in topic strings (e.g.,data_updatedvsDATA_UPDATED). Make sure the topic you publish matches exactly what you're subscribing to.
If PubSub still doesn't feel right for your project, here are other tried-and-true options for React 16.x:
Props Drilling + Callback Functions
For components with a direct parent-child or close hierarchy, pass data down via props, and use callback functions to send data back up. Perfect for simple apps or small component trees.Context API
React 16.3+ introduced the Context API, which is ideal for cross-component communication without props drilling. Create a context, wrap your app (or a section of it) in a Provider, then access the context in any child component withuseContext(function components) orContext.Consumer(class components).Quick example:
// Create a context const AppContext = React.createContext(); // Parent component as Provider function ParentComponent() { const [sharedData, setSharedData] = useState(null); return ( <AppContext.Provider value={{ sharedData, setSharedData }}> <SenderComponent /> <ReceiverComponent /> </AppContext.Provider> ); } // Sender component function SenderComponent() { const { setSharedData } = useContext(AppContext); return <button onClick={() => setSharedData('Hello via Context!')}>Send Data</button>; } // Receiver component function ReceiverComponent() { const { sharedData } = useContext(AppContext); return <div>Received: {sharedData}</div>; }State Management Libraries (Redux/MobX)
For larger apps with complex state flows, libraries like Redux (or Redux Toolkit, which simplifies setup) or MobX let you manage global state. Components dispatch actions to update state, and subscribe to state changes as needed.Callback Props via Common Parent
For sibling components, use their common parent as a middleman. The sender calls a parent-provided callback, which updates the parent's state, and the parent passes that state to the receiver via props.
内容的提问来源于stack exchange,提问作者lx6002

