jQuery is a widely used JavaScript framework for frontend web development. Some of its main strengths include easily referencing DOM elements, applying actionable items to elements—such as logic when clicking a button—and extensibility with a wide array of libraries already available. However, jQuery tends to do a lot of things that standard JavaScript can already do. Additionally, state management isn't ready-baked, which React.js already solves as its primary feature.
Companies like Github are starting to move away from jQuery toward other things, even vanilla JavaScript. If you plan to slowly transition your existing jQuery code to React.js, this guide will show you a few things you might want to watch out for.
Both jQuery and React.js reference target DOM elements to add additional processing, but their approaches are fundamentally different. Given the following HTML:
1<button id="btn-click">
2 Click Me
3</button>
How does each JavaScript framework attach clickable function logic to it?
1var $btnClick = $("#btn-click");
2
3$btnClick.on("click", function() {
4 alert("Button was clicked!");
5});
As you can see in jQuery, a developer would have to first reference the DOM element using the $()
function and passing either an id reference #
or a class reference .
. The click-event handler is then passed as a first argument string to the on()
function call of a queried element. The second argument is the function itself, which in this case simply alerts, "Button was clicked!"
If in jQuery, JavaScript is treated separately from HTML elements (thus the "query" part), React.js treats the rendered HTML UI as part of the container in what's referred to as a component. The component will contain all the necessary elements to be rendered in a target <div>
. The <button>
element itself will not be part of the initial HTML. Instead, you might have the following <div>
element:
1<div id="react-root"></div>
You would first have to define a component in a separate JavaScript file that renders the button:
1import React from 'react';
2
3export default class ButtonComponent extends React.Component {
4 constructor(props) {
5 super(props);
6 }
7
8 handleButtonClicked() {
9 alert("Button was clicked!");
10 }
11
12 render() {
13 return (
14 <div>
15 <button onClick={this.handleButtonClicked.bind(this)}>
16 Click Me
17 </button>
18 </div>
19 );
20 }
21}
All HTML elements to be rendered by a component are returned as JSX, an extension to JavaScript that allows declaration of HTML-like elements in React.js to define how an interface should be rendered. Notice that no id
attribute was set to the <button>
element. Instead, you attach an event handler that points to the method definition of handleButtonClicked()
. You include a .bind(this)
to allow the value of this
to be retained throughout the function call. This is a way to pass the instance of the component itself, exposing other methods both innate to a React.Component
, such as setState()
, or user-defined. You could say that no explicit reference was needed. The main difference compared to jQuery is that a React.js component will store all its UI needs as opposed to jQuery, which assumes that the UI element is rendered in HTML.
Managing the value of a JavaScript variable within a page can tend to get messy. For example, suppose you have a variable called message
representing a shoutout in your application. You'd like to have that message
displayed within a container <div>
like so:
1<div id="message">Message goes here</div>
In a jQuery approach, everything is still read from top to bottom. You might have the following code to first extract the current message:
1var message = $("#message").html();
To update the message, you have to reference the <div>
again and insert the new value:
1var message = "New message"; // Normally set by some other logical routine
2
3$("#message").html(message);
One downside to this approach is that the message has to be set multiple times—once for extracting the value and again for assigning a new value to it. Furthermore, additional code is needed to insert the message
back to the target <div>
. This tends to get messy, especially if you have another routine that might set a new value for message
. In that case, you would have to call $("#message").html(message)
again.
React.js solves this problem by maintaining a single instance of a variable through a component's state
. Each React.js component will have a state
object defined within it and is initinalized in the component's constructor. For example, suppose that you want to maintain that same message
value, and whatever logical routine would affect its value would automatically reflect in the component's UI. You might have the following:
1import React from 'react';
2
3export default class MessageComponent extends React.Component {
4 constructor(props) {
5 super(props);
6
7 this.state = {
8 message: ""
9 }
10 }
11
12 updateMessage(message) {
13 this.setState({
14 message: message
15 });
16 }
17
18 render() {
19 return (
20 <div>
21 {this.state.message}
22 </div>
23 );
24 }
25}
Notice that you set the message
initially in the component's state
within the constructor. The component has a method called updateMessage(message)
, which in turn calls a component's setState()
method to update the value of message
. The idea here is that every time setState()
is called, the component will re-render the UI as called in render()
, since render()
returns JSX that displays the message
via this.state.message
with whatever value it currently has.
React.js may seem complicated at first, but in terms of maintainability in the long run, it tends to keep everything organized by using proper state management. jQuery is easy to use but tends to get messy as more code is added to the mix. If you plan to migrate to React.js from a jQuery setup, always keep in mind the following:
setState()
will invoke a re-render of the component's UI via render()
together with the updated state values.