This is an updated version of one my older blogs: Old Post
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.
Top comments (0)