React.js Basics – The DOM, Components, and Declarative Views Explained

React.js has taken the web development world by storm since its initial release by Facebook in 2013. It has quickly become one of the most popular JavaScript libraries for building dynamic, interactive user interfaces. In fact, according to the State of JS 2020 survey, React is used by 80% of respondents, making it the most widely adopted front-end framework.1

But what exactly is React and why has it become so ubiquitous? In this in-depth guide, we‘ll dive into the fundamentals of React from the perspective of a seasoned full-stack developer. We‘ll explore key concepts like the DOM, components, declarative views, JSX, props, state, and more. By the end, you‘ll have a solid understanding of how React works under the hood and how to leverage its power for your own projects.

Understanding the DOM

To understand how React works its magic, we first need to take a step back and look at how browsers render web pages. When you load a website, the browser parses the HTML and builds a Document Object Model (DOM), which is a tree-like structure representing the page‘s content. Each HTML element becomes a node in this tree.

Traditionally, web developers would use JavaScript or jQuery to manually update the DOM when data changed – a process that was cumbersome, error-prone, and inefficient. Every time the DOM needed to be updated, the browser would have to recalculate the CSS, do a layout, and repaint the screen. For complex apps with many elements and frequent updates, this could lead to sluggish performance.

React solves this problem by utilizing a virtual DOM – a lightweight copy of the actual DOM kept in memory. When data changes in a React app, it first updates the virtual DOM. React then compares this updated virtual DOM with a snapshot of the previous virtual DOM, figures out what changed, and updates the real DOM accordingly. This process is called reconciliation.2

By minimizing direct manipulations to the real DOM, React can update the UI very efficiently. According to benchmarks, React can handle updates to a list of 10,000 elements in less than a second.3 This makes for lightning-fast user interfaces that feel snappy and responsive.

React‘s Component-Based Architecture

The virtual DOM alone doesn‘t account for React‘s popularity. Its real power comes from its component-based architecture. In React, the user interface is broken down into small, reusable pieces called components.

A component is a self-contained piece of code that encapsulates its own structure, styles, and behavior. Components can range in granularity from a simple button to a complex form or even an entire page. By composing an app from modular components, React code becomes more reusable, maintainable, and scalable.

Here‘s a simple example of a functional React component that renders a "Hello, World!" message:

function Greeting() {
  return ;
}

This code might look a bit strange if you‘re used to HTML. That‘s because it‘s using JSX – a syntax extension to JavaScript that allows you to write HTML-like code in your JavaScript files. When compiled, JSX gets transformed into regular JavaScript function calls that create React elements.

While you could write React without JSX, it makes your code much more readable and intuitive. With JSX, you can keep your component‘s structure, styles, and behavior all in one place. No more juggling separate HTML, CSS, and JS files!

Here‘s how that same component would look in pure JavaScript without JSX:

function Greeting() {
  return React.createElement(‘h1‘, null, ‘Hello, World!‘);
}

As you can see, JSX is much more concise and easier to understand at a glance.

Data Flow in React: Props and State

React components can receive data from their parent components via props (short for "properties"). Props are essentially arguments passed to a component, allowing it to be dynamic and reusable.

For example, let‘s modify our Greeting component to accept a name prop:

function Greeting(props) {
  return ;
}

We can then use this component by passing it a name:

<Greeting name="John" />

This would render:

Props are read-only, meaning a component cannot modify its own props. If a component needs to manage changing data, it can do so via state.

State is data that is internal to a component and can change over time. When a component‘s state changes, React automatically re-renders the component to reflect the new state.

Here‘s an example of a component using state to manage a counter:

import React, { useState } from ‘react‘;

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

In this example, we‘re using the useState hook to manage the component‘s state. Hooks are a new addition in React 16.8 that let you use state and other React features without writing a class.4

The useState hook returns a pair: the current state value and a function that lets you update it. You can call this function from an event handler or somewhere else. It‘s similar to this.setState in a class, except it doesn‘t merge the old and new state together.

Class Components vs Functional Components

Prior to the introduction of hooks, stateful logic could only be used in class components. A class component is a JavaScript class that extends React.Component and has a render method:

class Greeting extends React.Component {
  render() {
    return ;
  }
}

Class components can have local state and lifecycle methods. They are more complex than functional components and require you to understand how this works in JavaScript.

With the addition of hooks, functional components can now also have state and lifecycle-like features, making them capable of replacing most class components. This has led to a shift in the React community towards favoring functional components, as they are simpler, more concise, and avoid the pitfalls of this.5

Component Lifecycle

Each component in React has a lifecycle – a series of methods that are called at different stages of a component‘s existence. Understanding the component lifecycle is crucial for managing side effects, optimizing performance, and preventing memory leaks.

The main lifecycle methods are:

  • componentDidMount: Called after the component is rendered to the DOM. This is a good place to initialize third-party libraries, start timers, or make API calls.
  • componentDidUpdate: Called after the component updates. Use this to operate on the DOM when the component has been updated.
  • componentWillUnmount: Called right before the component is unmounted and destroyed. Use this to clean up timers, cancel API calls, or remove event listeners.

Here‘s an example of using lifecycle methods in a class component:

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>

        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

In functional components, you can use the useEffect hook to handle side effects like subscriptions, timers, logging, and more. It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in React classes, but unified into a single API.6

Declarative Views

One of React‘s core tenets is declarative programming. In a declarative style, you tell React what you want the UI to look like, and it figures out how to update the DOM to match that description.

This is in contrast to imperative programming, where you directly change individual parts of the app in response to various events. With imperative code, it can be harder to see the relationships between events and all the edge cases you need to handle.

React‘s declarative approach abstracts away the manual DOM manipulation, making your code more predictable and easier to debug. You simply update a component‘s state, and React automatically re-renders the component with the updated state.

For example, consider this imperative jQuery code for updating a list:

$(‘#list‘).append(‘<li>item</li>‘);

In React, you would handle this declaratively by updating the state that contains the list of items:

function List() {
  const [items, setItems] = useState([]);

  function addItem() {
    setItems([...items, ‘item‘]);
  }

  return (
    <ul>
      {items.map((item, index) => <li key={index}>{item}</li>)}
    </ul>
  );
}

Here, when the addItem function is called, it updates the items state by appending a new item. React then re-renders the component, and the new item automatically appears in the list.

The React Ecosystem

React‘s simplicity and flexibility have spawned a rich ecosystem of tools and libraries. This ecosystem is one of React‘s greatest strengths, providing a wide range of solutions for common problems and use cases.

Some of the most popular tools in the React ecosystem include:

  • Create React App: A tool that sets up a new React project with a pre-configured build pipeline and development environment.
  • Redux: A predictable state container for managing global application state.
  • React Router: A collection of navigational components that compose declaratively with your application.
  • Axios: A promise-based HTTP client for making API requests.
  • Material-UI and React Bootstrap: UI component libraries that provide pre-built, customizable components following popular design systems.

These are just a few examples – there are hundreds of high-quality React libraries and tools available, each solving a specific problem in the React development process.

React‘s Future

React‘s popularity shows no signs of slowing down. Facebook continually invests in React‘s development, with a strong emphasis on performance, developer experience, and new features.

One of the most anticipated updates is React 18, which introduces several new features and improvements:7

  • Automatic Batching: React will automatically batch multiple state updates into a single re-render for better performance.
  • Transitions: A new API for telling React which updates are urgent and which can wait, allowing for smoother user interactions.
  • Suspense: A mechanism for declaratively specifying loading states, allowing for easier async data management.

These upcoming features show that React is committed to staying at the forefront of web development, constantly evolving to meet the needs of modern applications.

Conclusion

React has revolutionized the way we build user interfaces. Its component-based architecture, declarative syntax, and powerful ecosystem make it an invaluable tool for any web developer‘s toolkit.

By understanding React‘s key concepts – the virtual DOM, components, props, state, and lifecycle methods – developers can create robust, maintainable, and efficient applications. And with the continued evolution of the React library and its surrounding ecosystem, it‘s an exciting time to be a React developer.

Whether you‘re building a small website or a large-scale enterprise application, React provides the flexibility and performance to meet your needs. Its popularity in the industry and the in-demand skills it provides make learning React a smart career move for any web developer.

So dive in, start building, and experience the power of React for yourself!

References

  1. State of JS 2020 Survey. https://2020.stateofjs.com/en-US/technologies/front-end-frameworks/
  2. React Docs – Reconciliation. https://reactjs.org/docs/reconciliation.html
  3. DOM vs. Virtual DOM in React. https://www.codecademy.com/articles/react-virtual-dom
  4. React Docs – Hooks Intro. https://reactjs.org/docs/hooks-intro.html
  5. React Functional Components, Props, and JSX – React.js Basics. https://www.freecodecamp.org/news/react-components-jsx-props-for-beginners/
  6. React Docs – Effects Hook. https://reactjs.org/docs/hooks-effect.html
  7. React v18.0. https://reactjs.org/blog/2022/03/29/react-v18.html

Similar Posts