How do I implement this cool new thing into my old busted site?. Many tutorials show how to start from scratch but many of us in the real world don't have that luxury.
In this tutorial I'll give a few basic examples on how to "Sprinkle In" ReactJS and replace some existing code written in jQuery.
I was tasked recently with taking a large feature written solely with jQuery and rebuilding it in React. The process was daunting because of the sheer amount of jQuery dispersed throughout the codebase. Building entire UIs with jQuery is very possible (we've been doing it for years) but is difficult to accomplish in a clear and well-maintainble manner that scales.
Whether you're using Angular, Ember, Vue, React, or just jQuery, you're probably trying to accomplish the same thing developers have been doing for years:
Render HTML > Receive User Events > Rerender HTML
Because jQuery relies so heavily on selectors like
find for a
Relying heavily on
#IDs to select and manipulate your HTML can be brittle.
So, what if your code is laced with jQuery or built on another framework entirely, how do you start replacing bits of UI with something like React?
Wrapper / Container Element
Whether the application is using jQuery or the next popular framework, most of the time there will be some sort of root element which wraps a piece of UI. If the codebase is using jQuery for a feature there is usually an element that acts like a wrapper selector. The wrapper element is selected using jQuery and utilized to dynamically make updates to the DOM.
<!-- .MyAwesomeFeature acts as a container to select and manipulate child components with jQuery. --> <div class="MyAwesomeFeature"> <div class="MyAwesomeFeature__title"></div> <div class="MyAwesomeFeature__image"></div> </div> <script> var container = $(".MyAwesomeFeature"); $(".MyAwesomeFeature__title", container).text("Hello World!"); // Other DOM changes, event handlers, etc... </script>
Isolated vs. Shared State
Something to look for in your existing application is whether the state of your feature is
isolated to a single container element or is
shared between multiple elements.
Isolated State - The state of the feature is isolated to a container element. Any interactivity with the feature via buttons, input fields, etc... is found within this wrapper / container element.
Shared State - The state of the feature is split between multiple elements. An example is a calendar being updated from a date dropdown from another place on the page. The menu and the calendar are in separate containers but share state and functionality.
I'm going to give 4 examples to demonstate the idea of Shared / Isolated state with jQuery and then ReactJS.
Let's say we have an existing web application which shows an emoji and a button to click and randomly display a new emoji. The code below is an example of a typical jQuery application where we select the most parent level item
.mood-container and make changes dynamically.
Here's the HTML for this example:
<!-- Demonstrates how jQuery can be used to use a container as a selector and update the content within. --> <div id="mood-container"> <div class="Mood"> <div class="Mood__emoji"></div> <div class="Mood__name">[ Emoji Placeholder ]</div> <button class="Mood__button">Random Mood</button> </div> </div>
This isn't the only strategy to make DOM changes via jQuery but is very common.
component. The result is a more reliable, maintainable, and reusable piece of functionality.
This helps tremendously when working with large applications due to the rendering and updating being found together inside the
All frameworks typically:
- Mount to a specified container (Like a div with the
- Render content to that container.
- Is responsible for keeping track of and updating the content within the container.
- Is sometimes responsible for the removal of the container.
Here's our new HTML after integrating React:
<!-- Demonstrates how ReactJS mounts itself to a container and takes it from there. --> <div id="mood-container" />
We can easily do this with jQuery, however, things become muddled when one area of the site dynamically effects another area of the site using mere selectors alone. Again, when you use
#IDs as selectors to manually manipulate the DOM, you're responsible for the overhead of keeping track of everything.
In this example we're sharing the mood name via the selectors
.Mood__button-name and updating the emoji in one container with a button in a separate container. This can probably be cleaned up a bit, but regardless, things get dirty pretty quick when trying to manage all of this with jQuery selectors alone.
In ReactJS, there are essentially two commonly used way of sharing state across multiple components:
- Wrap the components in a container to manage state and pass data / functions down as props to child components.
- Use something like Redux to place state and actions at the global level and connect your components to it.
Using a Container for Shared State
This a very common practice especially for SPAs or pieces of UI that are fully rendered with React. Because we want our components to communicate with one another, we wrap them in a parent level component and have it pass down properties to update each child component. This is essentially how ReactJS works out of the box and is nothing new.
This method works well in scenerios where you have the ability to wrap much of the UI with a single parent component. This isn't the case in many previously established applications but depending on the layout of your UI could be an option.
Using Redux for Shared State
Libraries like Redux (and the flux variations) make it easier for multiple components to communicate from different areas of your application. This shared state allows you to connect actions and state properties to your components by updating the global object Redux gives you.
Hopefully this gives you a good understanding of what to look for and how to integrate ReactJS into your existing application. The main takeaway should be that if you're using jQuery for a piece of UI than you can most likely replace the container element with a mounted React component. If you need to share state across multiple components than you can use the container method or integrate a library like Redux.
Thanks for reading!
-Andrew Del Prete