React

React is a JavaScript library for creating web pages, meaning that it runs in the browser, creating the DOM stuff that we want the page to contain. This is similar to the work we did in the Quizzes assignment when we created DOM elements (multiple choice questions) from an array of data.

Unfortunately, this is essentially a whole new language, called JSX, that combines HTML and JavaScript, where we build JavaScript functions that create web page components. So, it has a steep learning curve.

This reading will give you a slight familiarity with it but will not go into depth.

References

Depending on your time and interest, you can learn more from the following

Tic Tac Toe Tutorial

The following is directly from the React tic-tac-toe tutorial.

TTT tutorial sandbox

Take a few minutes to play the game and poke around in the DOM with the inspector.

Page Template

If you do a "view source" you'll see that the page starts pretty empty:

<body>
  <div id="root"></div>
</body>

Everything else is built by JavaScript

JSX functions

Here are two examples of JSX functions. The first is pretty simple and it builds a square for the game, as a button with an event handler.

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

The next function is much more elaborate. It has a number of local functions having to do with game play, and then builds the board as a 3x3 arrangements of <Square> elements.

function Board({ xIsNext, squares, onPlay }) {
  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

Let's focus on handleClick for a bit. This is the event handler that runs when we click on a square. (Well, not exactly. There's an arrow function for each square that calls this function with an argument depending on what square it is, much like we did in Concentration.

  function handleClick(i) {
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    onPlay(nextSquares);
  }

The first if statement says if there's already a winner or this square is occupied, return immediately, so the click has no effect.

The next part copies the entire board and fills in either an 'X' or an 'O', depending on what move it is.

We won't dig more into the code. If you are interested, the tutorial develops the game carefully, motivating each improvement in the code.

Discussion

Notice that the JS code that implements the game mechanics is tightly integrated with the JS code that builds the game HTML elements. Thus, if you decide to modify one, you're in the right file to modify the other.

Historically, HTML code and JS code were kept separate, with HTML giving the basic structure of the page, and JS adding behavior. Furthermore, the JavaScript behavior was optional, using the ideas of progressive enhancement that we discussed earlier in the context of Ajax. But as the web evolved, JavaScript became more essential and less optional, and support for JavaScript became more widespread. For example, a recent survey by WebAIM, people who study and support accessibility on the web, found that over 99% of respondents used a web browser that supported JavaScript, even if they used a screen reader.

WebAIM Survey from May 2021 to June 2021

So, nowadays, it makes more sense to integrate HTML and JS than it did even 10 years ago. React is one way to do that.

The results from the survey of users of screen readers is reassuring, but notice that if someone uses a web scraper to access the Tic-Tac-Toe page, all they will see is:

<body>
  <div id="root"></div>
</body>

So, in my opinion, it still makes sense to build essential structure and content on the server rather than in the browser using React. But for interactions, React does make some sense.

Advantages

React.js is a popular JavaScript library for building user interfaces. Some of the advantages of React.js over alternatives are:

  • Virtual DOM: React.js uses a virtual DOM, which is a lightweight representation of the actual DOM. This allows React.js to efficiently update only the parts of the page that need to be changed, rather than re-rendering the entire page.
  • Component-based architecture: React.js uses a component-based architecture, which makes it easier to build complex UIs by breaking them down into smaller, reusable components.
  • One-way data flow: React.js uses a one-way data flow, which makes it easier to debug and understand how data is flowing through the app.
  • Large community and ecosystem: React.js has a large and active community, which means that there are many resources available for learning and troubleshooting. There are also many third-party libraries and tools available that integrate well with React.js.
  • Performance: React.js is known for its high performance, which is due in part to its use of the virtual DOM and its ability to efficiently update the UI.
  • Cross-platform compatibility: React.js can be used to build both web and mobile applications, which makes it a versatile choice for developers.

Overall, React.js is a powerful tool for building complex user interfaces that are both efficient and easy to maintain. Its popularity and active community also make it a good choice for developers who want to stay up-to-date with the latest web development trends.

Disadvantages

While React.js has many advantages, there are also some potential disadvantages to consider:

  • Learning curve: React.js has a relatively steep learning curve, especially for developers who are new to the library or to web development in general.
  • JSX syntax: React.js uses a syntax called JSX, which can be confusing for developers who are used to working with HTML and JavaScript separately.
  • Limited scope: While React.js is well-suited for building user interfaces, it is not a full-fledged framework and does not include all the tools and functionality needed for building a complete application.
  • Performance issues with large apps: While React.js is generally known for its high performance, it can become slower and more resource-intensive as the app grows in complexity and size.
  • Requires additional tooling: In order to use React.js, developers often need to install additional tooling, such as a package manager, a build system, and a compiler.
  • Fragmented ecosystem: While React.js has a large and active community, the ecosystem can be fragmented, with many different libraries and tools competing for attention and adoption.

Overall, while React.js is a powerful and popular library for building user interfaces, it may not be the best choice for every project or every developer. It's important to carefully consider the pros and cons of React.js and to evaluate other alternatives before making a final decision.

Virtual DOM vs Real DOM

The real DOM (Document Object Model) is a tree-like structure that represents the structure of an HTML document. When a web page is loaded in a browser, the browser creates a real DOM that includes all of the HTML elements on the page, along with their attributes and content.

The virtual DOM, on the other hand, is a lightweight representation of the real DOM that is used by React.js to optimize the process of updating the user interface. When a user interacts with a React.js application and triggers a change, React.js updates the virtual DOM, which is a representation of what the real DOM should look like after the change has been made.

React.js then compares the updated virtual DOM with the previous version of the virtual DOM, and calculates the minimum set of changes needed to bring the real DOM in sync with the updated virtual DOM. This process is known as "reconciliation."

One of the key benefits of using the virtual DOM is that it can make updates to the user interface more efficient. Instead of updating the entire real DOM every time a change is made, React.js can update only the parts of the real DOM that have changed, which can result in faster and smoother updates.

In summary, the main difference between the virtual DOM and the real DOM is that the virtual DOM is a lightweight representation of the real DOM that is used by React.js to optimize the process of updating the user interface. By updating only the parts of the real DOM that have changed, React.js can make updates to the user interface more efficient and reduce the overall time required for rendering changes.

Rendering of HTML

The fact that the HTML is rendered in the browser means that React apps don't work well with web scrapers or any client that doesn't run the JavaScript. React.js applications rely on JavaScript to render the user interface in the browser, which means that they may not work as expected for clients that do not support JavaScript, such as web scrapers or older browsers.

When a React.js application is loaded in a browser, the JavaScript code is executed, which generates the HTML that is ultimately displayed to the user. This means that any clients that do not execute JavaScript will not be able to see the final HTML output of the application, and may not be able to interact with the application as intended.

However, it's important to note that this is not unique to React.js — any client-side JavaScript application will have similar limitations. In general, if you need to support clients that do not support JavaScript or are not able to run JavaScript, you may need to consider alternative approaches, such as server-side rendering or using a different technology stack altogether.

Summary

React is a whole new way to build web pages, combining HTML and JS in reusable components that are a lot like JS function calls that build DOM elements. The code can be tightly integrated with the JS event handlers that operate on it.