Writing

React 101: Prerequisites

文章發表於

Before diving into React, it's helpful to understand some foundational concepts that you'll encounter frequently in both learning and developing with React.

HTML Structure

React is a JavaScript library for building user interfaces, and the foundation of any user interface (web page) is HTML and its tree-like data structure. Take the following example:

<ul>
<li>Apple</li>
<li>Banana</li>
<li>Peach</li>
</ul>

Here, ul is the parent element of the li items, and conversely, the li elements are children of ul. This parent-child relationship forms a tree data structure, which we can manipulate through operations like traversal or CRUD.

ul
/ | \
/ | \
li li li
(Apple)(Banana)(Peach)

DOM

Developers use HTML to construct web pages. When a browser reads HTML code, it creates corresponding objects in memory for each HTML element and organizes them into a tree structure with root, parent, child, and grandchild nodes, forming a hierarchical relationship. This tree of objects is the DOM (Document Object Model), which the browser uses for subsequent rendering.

The DOM is also mutable. Even after the browser has rendered the page, we can still modify the DOM tree. When we change the DOM, the browser re-renders and updates what the user sees, all through browser-provided APIs like appendChild and removeChild.

<!DOCTYPE html>
<html>

<head>
  <title>Parcel Sandbox</title>
  <meta charset="UTF-8" />
  <link rel="stylesheet" href="/styles.css" />
</head>

<body>
  <h1>Hello world</h1>
</body>

</html>

This illustrates that building dynamic web pages primarily involves manipulating the DOM. However, as web pages grow more complex, inefficient DOM operations can lead to performance issues. Manipulating the DOM has a cost—the browser must update the DOM and repaint the screen—so developers need to find more effective ways to manage this code.

Declarative vs. Imperative Programming

Declarative and imperative programming are two different programming paradigms. Imperative programming describes how to accomplish a task step by step, while declarative programming specifies what you want to achieve.

For example, if you want to go somewhere, imperative programming is like giving a driver detailed turn-by-turn directions: "Go straight for 500 meters, turn right at the 7-Eleven, after two traffic lights turn left..." Declarative programming is like using Google Maps: you just enter your destination, and the system plans the best route for you.

However, declarative programming is essentially an abstraction built on top of imperative programming. This doesn't mean there's no imperative code underneath; every declarative system relies on imperative code to execute explicit instructions.

For instance, the map function is implemented using a for loop under the hood. It provides an abstraction layer so developers using map don't need to worry about loop details, index management, or array bounds checking, allowing them to focus on "what transformation to apply to each element."

Array.prototype.myMap = function(callback, thisArg) {
const result = [];
for (let i = 0; i < this.length; i++) {
if (i in this) {
result[i] = callback.call(thisArg, this[i], i, this);
}
}
return result;
};
// [1, 2, 3, 4, 5].myMap(x => x * 2) // [2, 4, 6, 8, 10];

Similarly, when we write JSX in React, it ultimately gets transformed into a series of _jsx calls (or createElement in earlier versions) and DOM manipulation instructions. React handles the underlying imperative code for us, making it easier to build our web applications.

If you enjoyed this article, please click the buttons below to share it with more people. Your support means a lot to me as a writer.
Buy me a coffee