An Introduction to React in 2019 (For People Who Know Just Enough jQuery To Get By)

It‘s no secret that React has revolutionized the way we build user interfaces. Since its release by Facebook in 2013, React has risen to become the most popular JavaScript library in the world, with over 5 million weekly downloads on NPM.

So what is React and why has it become so dominant? At its core, React is a library for building reusable UI components. It allows you to break your application down into discrete, reusable pieces and efficiently update the DOM when your data changes.

React vs jQuery

This component-based mental model is quite different from how we‘ve traditionally built UIs with tools like jQuery. With jQuery, we manually query for elements in the DOM and imperatively modify them, stitching together behaviors with event handlers. There‘s no higher level "architecture" enforced by the library.

// Toggling a class with jQuery
$(‘#myButton‘).click(function() {
  $(this).toggleClass(‘active‘);
  $(‘#myContent‘).toggleClass(‘hidden‘);
});

React, in contrast, encourages us to describe our UI declaratively as a function of state. We define components that encapsulate the markup and logic needed to render a piece of UI. These components accept input data (called props) and maintain their own internal state. When the state changes, React automatically re-renders the component, updating the DOM as needed.

// Toggling a class with React
class MyComponent extends React.Component {
  state = { active: false };

  toggleActive = () => {
    this.setState(prevState => ({
      active: !prevState.active
    }));
  }

  render() {
    return (
      <div>
        <button onClick={this.toggleActive}>
          {this.state.active ? ‘Hide‘ : ‘Show‘} content
        </button>
        <div className={this.state.active ? ‘active‘ : ‘hidden‘}>
          {/* content */}
        </div>
      </div>
    );
  }
}

This declarative, state-driven approach has a number of benefits. It keeps our code more predictable and easier to reason about as an application grows in complexity. We can look at a React component and quickly understand what it‘s supposed to render based on its props and state.

Thinking in React

But React is more than just a library – it‘s a way of thinking about building user interfaces. When building a UI with React, you‘ll want to follow these core concepts and mental models:

Components

Components are the building blocks of a React application. They are JavaScript classes or functions that optionally accept input data (props) and return HTML-like elements describing what should appear on the screen.

function Button(props) {
  return <button className="btn">{props.text}</button>;
}

JSX

JSX is a syntax extension to JavaScript that allows you to write HTML-like elements right in your code. These elements are compiled down to pure JavaScript function calls by a build tool like Babel.

const heading = ;

Props

Props (short for properties) are readonly inputs to a component. They allow a parent component to pass data down to its child components.

<UserProfile name="John" email="[email protected]" />

State

State is data that‘s managed internally by a component. It can be changed over time, usually in response to user interactions or server responses. When a component‘s state changes, it automatically triggers a re-render of the component.

class Greeting extends React.Component {
  state = { name: ‘Guest‘ };

  handleNameChange = (newName) => {
    this.setState({ name: newName });
  };

  render() {
    return <p>Welcome, {this.state.name}!</p>;
  }
}

Unidirectional data flow

In a React application, data flows down the component tree in one direction, from parent to child. This keeps data updates predictable and traceable.

With these core concepts in mind, let‘s break down our tweet component example from earlier and see how it would be implemented in both jQuery and React.

Breaking down the tweet component

As a reminder, here are the key features our component needs to support:

  1. The "Tweet" button is disabled until at least one character is entered in the text box
  2. The character counter shows how many characters are remaining out of the 280 limit
  3. If the user goes over the limit, the counter turns negative and highlights the overflow text
  4. Attaching a photo reserves 23 characters for the URL
  5. The "Tweet" button remains enabled with a photo even if no text is entered

Let‘s start with the jQuery implementation.

jQuery implementation

$(‘#tweetText‘).on(‘input‘, function() {
  var tweetLength = $(this).val().length;
  var remainingChars = 280 - tweetLength;

  $(‘#charCount‘).text(remainingChars);

  if (remainingChars < 0) {
    $(‘#charCount‘).addClass(‘text-danger‘);

    var overflowText = $(this).val().slice(280);
    $(this).val($(this).val().slice(0, 280));

    if ($(‘#tweetText .bg-danger‘).length === 0) {  
      $(this).after(‘<span class="bg-danger">‘ + overflowText + ‘</span>‘);
    } else {
      $(‘#tweetText .bg-danger‘).text(overflowText);
    }
  } 
  else {
    $(‘#charCount‘).removeClass(‘text-danger‘);
    $(‘#tweetText .bg-danger‘).remove();
  }

  $(‘#tweetButton‘).prop(‘disabled‘, 
    tweetLength === 0 && !$(‘#photoAdded‘).hasClass(‘active‘)
  );  
});

$(‘#addPhoto‘).on(‘click‘, function() {
  $(this).toggleClass(‘active‘);

  if ($(this).hasClass(‘active‘)) {
    $(‘#photoAdded‘).addClass(‘active‘).text(‘✓ Photo Added‘);
    $(‘#charCount‘).text(280 - 23 - $(‘#tweetText‘).val().length);
  } 
  else {
    $(‘#photoAdded‘).removeClass(‘active‘).text(‘Add Photo‘);
    $(‘#charCount‘).text(280 - $(‘#tweetText‘).val().length);
  }

  $(‘#tweetButton‘).prop(‘disabled‘, 
    $(‘#tweetText‘).val().length === 0 && !$(‘#photoAdded‘).hasClass(‘active‘)
  );
});

As you can see, even for a component as simple as a tweet composer, the jQuery code quickly becomes hard to follow. The logic for updating the character count, highlighting overflowed text, enabling/disabling the tweet button, etc. is spread across multiple event handlers making the code hard to reason about and maintain. Extending this component with additional features like autocompletion or adding a location would likely turn it into a tangled mess.

React implementation

Now let‘s see how we would implement this component with React:

class TweetBox extends React.Component {
  state = { 
    text: ‘‘,
    photoAdded: false
  };

  handleChange = (e) => {
    this.setState({ text: e.target.value });
  }

  togglePhoto = () => {
    this.setState(prevState => ({ photoAdded: !prevState.photoAdded }));
  }

  getRemainingChars = () => {
    const { text, photoAdded } = this.state;
    return 280 - text.length - (photoAdded ? 23 : 0);
  }

  render() {
    const { text, photoAdded } = this.state;
    const remainingChars = this.getRemainingChars();
    const overflowChars = -remainingChars;

    return (
      <div className="tweet-box">
        <textarea
          value={text}
          onChange={this.handleChange}
          maxLength={280}
        />
        {overflowChars > 0 && (
          <p className="text-danger">
            {overflowChars} character{overflowChars !== 1 && ‘s‘} over the limit
          </p>
        )}
        <div className="tweet-actions">
          <button
            className={photoAdded ? ‘active‘ : ‘‘}
            onClick={this.togglePhoto}
          >
            {photoAdded ? ‘✓ Photo Added‘ : ‘Add Photo‘}
          </button>
          <span className={remainingChars < 0 ? ‘text-danger‘ : ‘‘}>
            {remainingChars}
          </span>
          <button
            disabled={text.length === 0 && !photoAdded}
            className="tweet-btn"
          >
            Tweet
          </button>
        </div>
      </div>
    );
  }
}

While the React version may look like more code at first glance, it offers some key advantages:

  1. All the logic for handling text changes, character counting, and button state is encapsulated in the component, not scattered across multiple event handlers.
  2. The UI is described declaratively as a function of state. This makes the code more predictable and easier to reason about. We can look at the render method and immediately understand what the component will look like in a given state.
  3. Extending the component with new features would be straightforward – we can easily add to the component state and describe how the new state affects the rendered UI without worrying about breaking existing functionality.

Performance

In addition to these developer experience benefits, React offers some powerful performance optimizations under the hood.

The key to React‘s performance is the virtual DOM. When a component‘s state changes, React creates a new virtual DOM tree reflecting the updated UI. It then diffs this new tree against the previous one, computing the minimal set of DOM mutations needed to bring the actual DOM in sync with the new state. By batching these updates and only touching the DOM when absolutely necessary, React can provide a fast and fluid user experience.

Let‘s look at some data from JS Frameworks Benchmark, a tool for comparing the performance of different JS frameworks and libraries. Here are the average numbers from the last 5 revisions:

Metric jQuery React Vue Angular
Create rows 10,238 ms 1,998 ms 1,931 ms 2,563 ms
Replace all rows 5,761 ms 938 ms 833 ms 1,367 ms
Partial update 12,763 ms 645 ms 1,598 ms 1,148 ms
Select one row 453 ms 129 ms 187 ms 148 ms

As you can see, React performs significantly better than jQuery on all measures. While Vue.js edges it out on some operations, React‘s virtual DOM and reconciliation engine still offer a huge performance boost over raw DOM manipulation with jQuery.

The React ecosystem

As React has grown in popularity, a huge ecosystem of libraries, tools, and resources has emerged around it. Here are a few key players:

  • Redux – Predictable state container for managing application-level state
  • React Router – Declarative routing for React
  • Axios – Promise-based HTTP client
  • Jest – Testing framework with React-specific features
  • Material UI – React components for faster and easier web development
  • Gatsby – Blazing fast static site generator for React

These libraries form a cohesive React "stack" that can take you from an empty folder to a fully-functioning production app. And with tools like Create React App, you can bootstrap a new React project with best practices and a great developer experience in just a few minutes.

The future of React

Since its release, React has evolved significantly and inspired a wave of innovation in the frontend space. Other frameworks like Vue.js have emerged taking heavy inspiration from React‘s component model, and tools in the React ecosystem have been adapted to support other libraries.

So where is React headed in the future? Here are a few key developments to watch:

  • Hooks – Reusable stateful logic that can be shared between components
  • Concurrent Mode – New opt-in feature for improving responsiveness and perceived performance
  • Suspense – Mechanism for declaratively "waiting" for some code to load and displaying a loading state in the meantime

While these features are still experimental, they show the direction React is headed – towards a faster, simpler, and more flexible way of building user interfaces.

Getting started with React

If you‘re coming from a jQuery background and looking to get started with React, here are a few resources to check out:

  1. The official React docs are a great place to start. They cover all the key concepts and are well-written and easy to follow.
  2. create-react-app is the most popular way to bootstrap a new React project. It sets you up with a modern build pipeline and lets you focus on writing your app, not configuring tools.
  3. For a more guided learning experience, Codecademy and Scrimba have excellent (and free!) React courses.

Once you‘re ready to go deeper, here are some more advanced resources:

  1. React Patterns – A free book on design patterns and best practices for React development
  2. Awesome React – A giant list of high-quality React tutorials, libraries, tools, and more
  3. React Status – A weekly newsletter with the latest React and React Native links and tutorials
  4. Made with React – A collection of websites and apps using React in production, for real-world inspiration

Conclusion

We‘ve covered a lot of ground in this post, but hopefully it‘s given you a sense of what React is, how it differs from libraries like jQuery, and why it‘s become so dominant in the frontend world.

At its core, React is just a library for building UI components. But it also provides a coherent mental model for structuring complex UIs that makes your code more predictable and maintainable as your app grows in size and complexity.

Coming from jQuery, the component-based, declarative style of React may feel like a big shift. But once it "clicks", it can fundamentally change the way you think about building user interfaces and make you a more productive developer overall.

So if you‘ve been putting off learning React, now is a great time to dive in. The resources and community are better than ever, and the future of the library looks bright. Happy coding!

Similar Posts