DEV Community

bravemaster619
bravemaster619

Posted on • Edited on • Originally published at stackoverflow.com

2 1

Event-driven approach in React hooks?

I'd like to "fire an event" in one component, and let other components "subscribe" to that event and do some work in React.

For example, here is a typical React project.

I have a model, fetch data from server and several components are rendered with that data.

interface Model {
   id: number;
   value: number;
}

const [data, setData] = useState<Model[]>([]);
useEffect(() => {
   fetchDataFromServer().then((resp) => setData(resp.data));
}, []);

<Root>
   <TopTab>
     <Text>Model with large value count:  {data.filter(m => m.value > 5).length}</Text>
   </TobTab>
   <Content>
      <View>
         {data.map(itemData: model, index: number) => (
            <Item key={itemData.id} itemData={itemData} />
         )}
      </View>
   </Content>
   <BottomTab data={data} />
</Root>
Enter fullscreen mode Exit fullscreen mode

In one child component, a model can be edited and saved.

const [editItem, setEditItem] = useState<Model|null>(null);
<Root>
   <TopTab>
     <Text>Model with large value count:  {data.filter(m => m.value > 5).length}</Text>
   </TobTab>
   <ListScreen>
      {data.map(itemData: model, index: number) => (
          <Item 
             key={itemData.id} 
             itemData={itemData} 
             onClick={() => setEditItem(itemData)}
          />
      )}
   </ListScreen>
   {!!editItem && (
       <EditScreen itemData={editItem} />
   )}
   <BottomTab data={data} />
</Root>
Enter fullscreen mode Exit fullscreen mode

Let's assume it's EditScreen:

const [model, setModel] = useState(props.itemData);

<Input 
   value={model.value}
   onChange={(value) => setModel({...model, Number(value)})}
/>
<Button 
   onClick={() => {
       callSaveApi(model).then((resp) => {
           setModel(resp.data);
           // let other components know that this model is updated
       })
   }}
/>
Enter fullscreen mode Exit fullscreen mode

How can I let TopTab, BottomTab and ListScreen component to update data

  • without calling API from server again and
  • not passing updateData function as props

I'd like to fire an event (e.g. "model-update") with an argument (changed model) and let other components subscribe to that event and change their data.

Is it possible using React hooks?

How to implement event-driven approach in React hooks?

Please let me know your opinions. Leave comments here or help me in Stack Overflow!

23

I'd like to "fire an event" in one component, and let other components "subscribe" to that event and do some work in React.

For example, here is a typical React project.

I have a model, fetch data from server and several components are rendered with that data.

interface Model {

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (1)

Collapse
 
dceddia profile image
Dave Ceddia • Edited

You ruled out passing an updateData function down, but that is the "plain React way" to do this: pass a callback down, and children can call it when there's new data. Hooks don't change that model.

There are libraries that implement the observer pattern, like MobX, that can detect changes and re-render components that use the changed data.

There's also react-query, which is pretty much built to solve your fetching/updating/reloading data use case. It maintains a global cache of responses, and every query & mutation feeds into that same cache, so changes will cause the components using the data to re-render.

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more