Sunday, March 24, 2024

Advanced React Hacks 5/10 - "Old School" Events

Another "advanced" tip coming!

Consider the following situation
  • You're required to communicate between components in different locations at the component hierarchy. Perhaps they aren't even in a parent child relationship
  • Some functions are involved, maybe some loops. This code is already done, and already works.
  • Perhaps, some refs or other outside-of-React escape hatches are involved. This code is already done, and already works
  • And of course the usual restriction of a "professional" software developer -- don't change too much, and anything you change must be regression tested and so on and so on!
You consider several solutions
  • Since functions and loops are involved, you can't use hooks (at least not inside the functions or loops)
  • The code is already done; you don't want to refactor everything and besides you're not sure that refactoring everything will lead to a better solution anyway because it's a one-off
    • Ideally all the information should have been stored in a central location and flow down to all the required components, but that bus is gone
      • Besides, the days of storing a property, modifying it with two-way data binding and binding to that property are long since over (this isn't Knockout or Backbone!)
        • Besides, even if you did it, you would have to modify enormous amounts of already completed code, possibly create regressions, and pass down props many levels!
  • Seems like a perfect situation to use Redux (Redux Toolkit) or some other state management but besides the fact you can't use hooks, you don't want to mess with the global store and it seems wrong to use it for the one-off
  • You look at some solutions like HTML5 local storage, but that's already outside of React and you would somehow have to subscribe to local storage anyway
    • Besides, the usehook-ts package doesn't properly install
      • Besides, after copying the usehooks-ts package, it's a hook, so you can't use it in the functions anyway!
What do you do now? Is React so obtuse that you really can't deal with this situation in any way?


Are you doomed to a sprint carryover and total humiliation, just because React sucks monkey balls?



There is an answer
Forget React
Forget Hooks
Forget Frameworks
Forget react.dev documentation (except for this )


JAVASCRIPT




// inside a custom hook if you want to reuse this...
// put custom hook inside component you want to rerender...
// or just put this inside the component...

useEffect(() => {
  const func = {
    // code to subscribe to...
  }
  window.addEventListener('cool-event-name-make-it-constant', func);
  return () => window.removeEventListener('cool-event-name-make-it-constant', func);
});

...

// inside the function you want to trigger an event from
// Normal JavaScript!
// setTimeout is the secret sauce when dealing with refs! (may not be required)
setTimeout(() => {
  window.dispatchEvent(new Event("cool-event-name-make-it-constant"));
}, 10);



So remember the basics, and when React fails you, just use ordinary JavaScript

The dispatchEvent() method of the EventTarget sends an Event to the object, (synchronously) invoking the affected event listeners in the appropriate order. The normal event processing rules (including the capturing and optional bubbling phase) also apply to events dispatched manually with dispatchEvent().

Calling dispatchEvent() is the last step to firing an event. The event should have already been created and initialized using an Event() constructor.

The best documentation

Sometimes the old ways are the best ways


Hope this helps someone!

4 comments:

  1. The article presents an interesting React scenario where components need to communicate even when they are not directly connected through a parent-child relationship. The discussion of existing functions, loops, refs, and the need to avoid extensive refactoring makes the situation feel realistic, especially when a solution must work without introducing unnecessary changes or regression risks.

    The suggestion of using traditional JavaScript events provides a lightweight alternative when hooks or a global state-management solution may not be suitable. Developers working with component communication can explore these concepts further through a ReactJS Course, while gaining a clearer understanding of how React components interact within larger applications.

    ReplyDelete
  2. I also found the comparison with Redux, local storage, and hooks useful because it highlights that not every communication problem requires introducing another layer of application state. When an existing application has constraints around functions and loops, a simple event-based approach can sometimes address the immediate requirement without requiring a major architectural change. Developers interested in extending React knowledge to mobile applications can explore React Native Course as another component-based development approach.

    ReplyDelete
  3. The article ultimately reinforces the value of choosing a solution that matches the specific problem rather than automatically reaching for a framework feature or state-management library. The JavaScript event approach also provides an interesting pattern to experiment with in practical applications, and hands-on ReactJS Projects can provide opportunities to apply component communication and application architecture concepts in real projects.

    ReplyDelete