Using Custom Events to communicate between legacy jQuery code and new Framework code
Tags: react, javascript, legacycode, codequality
Published: 2021-06-02 17:52:13

*This is an updated version of one my older blogs: [Old Post](https://medium.com/@findniya/using-custom-events-to-communicate-between-legacy-jquery-code-and-new-framework-code-e34bb725c734)*

While writing a new feature using React one of my hurdles was figuring out a way to make the new React code and the old jQuery code communicate with each other. My new component, had to get date and time from the date picker written in jQuery code as users interacted with it. At this time I didn’t have the option to rewrite the date picker in React.

My solution to this problem was to use Custom Events.
The custom event was setup in the jQuery function to dispatch every time it returned a result. Then I setup the React component to listen for this custom event and update state.

###Let’s Look At Some Code Samples
**The React Component:**
```
const MyComponent ()=> {
    const [dateRange, setDateRange] = useState({from:'', to:''})

    return <div id='containerId' />
}
```
This component renders a div with an id that I will need for the jQuery to use. My state object has the keys from and to that needs the date and time information from the jQuery date picker.

###Part of jQuery Code handling the DatePicker:
```
setDateTime: function() {
  var from = moment(picker.from).utcOffset(this.utcOffset());
  var to = moment(picker.to).utcOffset(this.utcOffset());

  this.setView(from, to);
}
```

The above snippet is the small part of a larger file using global variables to trigger the `setDateTime` function. This then passes the `from` and `to` values to other functions in the jQuery file. Functionally the jQuery date picker works well, code wise though its super fragile and impossibly hard to figure how it all connects.

Thankfully the above snippet is all I needed. Every time the `setDateTime` function was triggered I need it to send the `from` and `to` values to my React component.

###Adding my custom event:
```
setDateTime: function() {
  var from = moment(picker.from).utcOffset(this.utcOffset());
  var to = moment(picker.to).utcOffset(this.utcOffset());
  var myEvent = new CustomEvent('dateTimeEvent', 
      { bubbles: true, detail: { dateTime: {from, to} });
    
    document.querySelector('#containerId').dispatchEvent(myEvent);
  this.setView(from, to);
}
```

As the `from` and `to` are set in the setDateTime function, I have my custom event named myEvent that then bubbles the dateTime object with these values. The event is dispatched to the `div` with the `id='containerId'` in my React component. This function does not in any way interfere with the rest of the jQuery code. It just passes the information I need without changing any other existing functionality.

###Update the React Component
```
useEffect(()=>{
  window.addEventListener('dateTimeEvent', 
  onDateTimeChange(e))
},[])
```

I added the event listener to the `useEffect`. Any time the `setDateTime` function in the jQuery is triggered the listener will capture `dateTime` object and pass it into my function `onDateTimeChange`.

```
const onDateTimeChange = (e) => {
   setDateRange({
      from: e.detail.dateTime.from,
      to: e.detail.dateTime.to
   })
}
```

Every time the `onDateTimeChange` is triggered it updates state in my React component with the date time value from the jQuery code.

In this way my new React component could coexist with the jQuery date picker without having to worry about the legacy code interfering. Plus the changes to the jQuery code were minimal and didn’t affect any of its existing functions.

###What The React Component Looks Like Now
```
const MyComponent ()=> {
    const [dateRange, setDateRange] = useState({from:'', to:''})

const onDateTimeChange = (e) => {
   setDateRange({
      from: e.detail.dateTime.from,
      to: e.detail.dateTime.to
   })
}

useEffect(()=>{
  window.addEventListener('dateTimeEvent', 
  onDateTimeChange(e))
},[])

    return <div id='containerId' />
}
```

This was an interim solution that allowed me to continue working on the new feature, without having to do a costly rewrite at the same time.