loading...

Event-driven approach in React hooks?

bravemaster619 profile image bravemaster619 Updated on ・2 min read

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>

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>

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
       })
   }}
/>

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!

Event-driven approach in React?

6

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 {

Posted on by:

bravemaster619 profile

bravemaster619

@bravemaster619

Have been a fullstack web developer for 5+ years. Top 10% Javascript & React answerer in Stack Overflow.

Discussion

markdown guide
 

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.