4. UseState, Hooks

Understanding useState and Hooks in React

What is State?

In React, the state is a built-in object that allows components to create and manage their own data. So, it's essentially the "memory" of a component. The state object is where you store property values that belong to the given component, and when the state object changes, the component re-renders.

What are Hooks?

Hooks are a new feature introduced in React 16.8 that allow you to use state and other React features without writing a class. They are functions that let you "hook into" React state and lifecycle features from function components.

The useState Hook

The useState Hook is a built-in function that allows you to add React state to function components. It takes the initial state as an argument and returns an array of two entries:

  1. The current state value (equivalent to this.state in classes),
  1. A function to update it (equivalent to this.setState in classes).

Here is a code example:

import React, { useState } from 'react';

function ScoreCounter() {
  const [score, setScore] = useState(0);

  const increment = () => {
    setScore(score + 1);
  };

  return (
    <div>
      <p>Score: {score}</p>
      <button onClick={increment}>Increase Score</button>
    </div>
  );
}

In the above example, useState(0) sets the initial value of score to 0. When the button is clicked, the increment function is called, which calls setScore to update the score value and re-render the component with the new state.

Understanding the Render Process

The rendering process in React consists of three phases: Triggering, Rendering, and Committing.

Triggering

This is the phase where the render process starts. It usually occurs when there are changes to the state or props.

Rendering

In this phase, React starts rendering the virtual DOM. At this stage, the render() method and the hooks are called.

Committing

In the commit phase, React makes the changes to the DOM to reflect the new state of the component. This is when the updated UI gets visible to the user.

The useImmer Hook

When dealing with complex state objects, it's often recommended to use the useImmer hook. It allows you to work with immutable state in a more convenient way by providing a function where you can produce the next state based on the current one, reducing the need for copying and spreading the state object. This is especially beneficial when dealing with large objects.

import { useImmer } from 'use-immer';

function MyComponent() {
  const [state, updateState] = useImmer({
    counter: 0,
    text: 'Hello, World'
  });

  function handleClick() {
    updateState(draft => {
      draft.counter++;
      draft.text = 'Hello, Immer';
    });
  }

  return (
    <div>
      <p>{state.counter}</p>
      <p>{state.text}</p>
      <button onClick={handleClick}>Click Me</button>
    </div>
  );
}

In this example, the updateState function receives a producer function, where we can mutate the draft directly to produce the next state. The useImmer hook takes care of the immutability behind the scenes.

Reference

The content in this document is based on the original notes provided in Azerbaijani. For further details, you can refer to the original document using the following link:

Original Note - Azerbaijani Version