Bricks and Bones of React

JSX

JSX (JavaScript XML) is a syntax extension for JavaScript that is commonly used with React.js to describe what the UI should look like. JSX allows you to write HTML elements and components in a syntax that looks similar to XML or HTML, but it gets transformed into regular JavaScript code. It provides a concise and expressive way to define the structure of React components.

JSX
const name = 'John';
const element = <h1>Hello, {name}!</h1>;

JSX is not required to build React applications, but it’s a popular and widely adopted syntax because it makes the code more readable and expressive. Under the hood, JSX is transformed into JavaScript using tools like Babel before it’s run in the browser.

Components

In React, a component is a reusable, self-contained building block for a user interface. Components are the fundamental units of a React application, and they can be thought of as custom, encapsulated pieces of code that can be composed together to build complex user interfaces. React applications are typically structured as a tree of components, where each component represents a part of the UI.

There are two main types of components in React: functional components and class components. However, with the introduction of React Hooks, functional components are now the preferred way to define components.

Props and State

In React.js, both state and props are fundamental concepts that play a crucial role in building dynamic and interactive user interfaces.

Props (Properties):

Props are a way to pass data from a parent component to a child component. They are read-only and should not be modified by the child component.

// Parent Component
const ParentComponent = () => {
  const name = "John";
  return <ChildComponent name={name} />;
}

// Child Component
const ChildComponent = (props) => {
  return <p>Hello, {props.name}!</p>;
}

In this example, the name variable in the ParentComponent is passed as a prop to the ChildComponent. Props are accessed in the child component through the props object.

State:

State is a way to manage and represent the internal state of a component. It is mutable and can be updated by the component itself.

// Class Component with State
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

In this example, the Counter component has an internal state (count), and when the “Increment” button is clicked, it updates its own state using the setState method. React then re-renders the component with the updated state.

Lifecycle Methods

In React, lifecycle methods are methods that get called at various stages in a component’s life, from its creation to its removal from the DOM. With the introduction of React Hooks, the concept of lifecycle methods has been extended to functional components as well.

Here are the main lifecycle methods in a class component:

Mounting

  • constructor(props): This is the constructor method where you initialize state and bind methods.
  • static getDerivedStateFromProps(props, state):This is a static method that is called before every render. It’s used to update the state based on changes in props.
  • render(): This method is responsible for returning the JSX that represents the component.
  • componentDidMount(): This method is called after the component is mounted to the DOM. It’s often used for making AJAX requests or setting up subscriptions.

Updating

  • static getDerivedStateFromProps(nextProps, nextState): Similar to the mounting phase, this static method is called before every render, but it’s used for updating the state based on changes in props.
  • shouldComponentUpdate(nextProps, nextState): This method is called before rendering, and it determines if the component should re-render. By default, it returns true, but you can optimize performance by returning false in certain conditions.
  • render(): Again, this method is responsible for returning the JSX that represents the component.
  • getSnapshotBeforeUpdate(prevProps, prevState): This method is called right before the changes from the virtual DOM are to be reflected in the DOM. It allows you to capture some information (e.g., scroll position) before the update.
  • componentDidUpdate(prevProps, prevState, snapshot): This method is called after the component is updated in the DOM. It’s often used for interacting with the DOM or performing side effects based on the update.

Unmounting

  • componentWillUnmount(): This method is called just before the component is unmounted from the DOM. It’s used for cleanup activities such as cancelling network requests or clearing up subscriptions.

Error Handling

  • static getDerivedStateFromError(error): This static method is called when there is an error during rendering. It’s used to update state based on the error.
  • componentDidCatch(error, info): This method is called after an error has been thrown during rendering. It’s used for logging error information.

With the introduction of React Hooks, functional components can use lifecycle methods through the useEffect hook, which allows you to perform side effects in functional components. The equivalent of componentDidMount, componentDidUpdate, and componentWillUnmount in functional components can be achieved using useEffect.

It’s important to note that with React Hooks, the lifecycle methods approach is still available, but the usage of useEffect is encouraged for better code organization.

Virtual DOM

React’s Virtual DOM is a key concept that contributes to the library’s efficiency in updating and rendering user interfaces. The Virtual DOM is a lightweight copy of the actual DOM (Document Object Model) that React maintains internally. When changes are made to a component’s state or props, React doesn’t immediately update the real DOM. Instead, it first updates the Virtual DOM.

Here’s how the Virtual DOM works:

Render Virtual DOM:

  • When a component’s state or props change, React triggers a re-render of that component.
  • The render method is called to create a new Virtual DOM representation of the component’s UI.

Diffing Algorithm:

  • After the new Virtual DOM is created, React uses a process called “reconciliation” or “diffing” to compare the new Virtual DOM with the previous one.
  • React identifies the differences (or “diffs”) between the old and new Virtual DOMs.

Minimizing DOM Operations:

  • Once the differences are identified, React calculates the most efficient way to update the actual DOM to reflect the changes.
  • Instead of updating the entire DOM tree, React calculates a minimal set of updates needed to bring the actual DOM in sync with the Virtual DOM.

Batched Updates:

  • React batch processes these updates and applies them to the real DOM in a single batch. This helps in optimizing performance by reducing the number of direct manipulations of the DOM.

Reconciliation:

  • React follows a “reconciliation” process to update the DOM efficiently. It updates only the parts of the DOM that have changed, rather than re-rendering the entire UI.

The Virtual DOM provides several benefits:

  • Performance Optimization: By minimizing the number of direct DOM manipulations, React reduces the performance bottlenecks associated with frequent updates.
  • Cross-Browser Compatibility: React abstracts away the differences in how browsers handle the DOM, ensuring consistent behavior across different browsers.
  • Declarative Syntax: Developers can work with a declarative syntax when defining components and let React take care of efficiently updating the DOM.

It’s important to note that developers typically interact with the Virtual DOM indirectly through the React API. They don’t need to manually manipulate the Virtual DOM; React takes care of it behind the scenes. The use of a Virtual DOM is a key factor in React’s ability to provide a smooth and responsive user experience.