So with this post, I am trying something different. I am just going to tell you about my experience thus far with taking an existing SPA created in Backbone + jQuery and migrating this SPA to React.
I am going to get straight into it, and therefore if you’re new to React, my suggestion would be to check out other blog posts as this will cover advanced topics.
Additionally, I know that many people have written articles & posted videos on such migration. However, when I was reading and watching those videos, I was still missing critical architectural info. So even though sample code and blog post example were made available to me, this still didn’t help me in what I needed to do.
Migration Planning Phase
After doing research, I presented a few ideas to my colleagues and Head of Development. There where two main ways of going about our migration:
- Hybrid Solution
- Complete Clean Refactor
Complete Clean Refactor
We start from the ground up and re-build everything. There’s a point in the life of a product where a complete clean refactor is not feasible. When you have a product that is successful and clients are happy. Yes, the underlying tech might be outdated, it might take longer to deliver new features and maybe its no-longer developer friendly.
Additionally, asking business just for a budget to refactor an existing product? It’s no wonder why business does not trust its tech people.
After presenting this information to the team, the Hybrid Solution was a clear winner.
Before joining the team, I had been working on a React SPA that used a NodeJs + Express API. I was working on both of these code bases. Additionally, we had a React Native application using the same API. Moreover, before that, I was working on an Angularjs (1.5) App. Therefore I had no Backbone experience. However, this would not be an issue.
So we had an idea that we should do a hybrid solution, but we didn’t know how we would do it? Therefore it was suggested that we start by prototyping this hybrid solution.
The Prototype Phase
This phase would last two weeks, and we would use the learning’s from this phase to create an architectural solution, which we will use going forward for our smooth react migration.
When I presented my solution to my colleagues, they were happy with the outcome. However, they challenged me to simplify the architecture and use Redux Architecture with Redux-Saga as middleware and making use of Redux-Saga side effects for rendering components onto the DOM. This would get rid of the iframe and simplify the middleware to dispatch actions to redux and sagas and make use of Backbone events. This way any new developer joining the project would not need to learn my custom middleware but use existing tech knowledge they know about Redux and Backbone.
The Final Architecture
I cannot post the actual code as that is company property. However, the beauty of these patterns I used during the prototype phase are so simple and straightforward that I have recreated them for this blog post.
Legacy SPA App
- React-Middleware – used for dispatching actions
So the Legacy SPA does not have a clue about React it just continues to run as it does currently. We have a React-middleware which dispatches actions from the Legacy SPA to Redux or Sagas.
Storing User Info in Redux
So example currently on our SPA when a User logs in, after login, the react-middleware dispatches an action with User login payload, this is sent to Redux and the User data is stored in our Redux store for use for by our React App.
Rendering/Mount React Component
This is probably one of the coolest things I learnt about React which is the possibility of rendering multiple components onto the DOM. Now I didn’t know React could do this. However, I recently learnt from a conference talk that this is how they use React at Facebook.
In our SPA we decided to use redux-sagas side-effects to also render components onto the DOM for us. Therefore, on the Legacy SPA, an action is dispatched with a DOM element ID. Then a saga listening to this action uses that element ID to render a component onto that DOM element using ReactDOM.render(). The great thing about this is we are respecting the Redux Architecture, by simple dispatching an action, this easy to understand even for new people joining our team.
Un-Rendering/Dismount React Component
Where are we now
We have just finished our first feature in React, and it is working great inside the Legacy SPA. We are about to start creating more new features using React rapidly. We will also start looking at converting existing functionality over to React. The remarkable thing about this Hybrid solution, is we are keeping business happy by delivering the features they want. We as developers have created a great developer experience for ourselves.