WittCode💻

React What is State?

By

Learn what React state is including how it works, why it's needed, how it's different than regular JavaScript variables, and more.

Table of Contents 📖

What is State?

React state is data that a component needs to keep in memory, or remember. For example, a users component might need to store a list of user information, a current country component might need to store the currently selected country, and so on.

React State and Re-renders

React state changes also cause a component to re-render so that the UI can be in sync with the new state. Regular JavaScript variables do not cause a component to re-render. In the code below, clicking the button increments the count variable. However, this isn't reflected in the UI as the component doesn't re-render.

const App = () => {
  let count = 0;

  const increment = () => {
    count = count + 1;
    console.log('Count is: ' + count);
  };

  // Increment is reflected in the logs but not the UI

  return (
    <>
      <h1>{count}</h1>
      <button onClick={increment}>Click</button>
    </>
  );
};

If we want our component to re-render, we need to manage some state.

const App = () => {
  const [count, setCount] = useState(0);
  console.log('Count is: ' + count);

  const increment = () => {
    setCount(count + 1);
  };

  return (
    <>
      <h1>{count}</h1>
      <button onClick={increment}>Click</button>
    </>
  );
};

Now the count variable is managed by state. Therefore, clicking the component's button causes the component to re-render.

React State and Persistence

React state also persists between re-renders while regular JavaScript variables do not. In the code below, clicking the button increments the count state triggering a re-render.

const App = () => {
  const [count, setCount] = useState(0);
  let regularVar = 0;
  console.log('Count is: ' + count); // Managed by React, increments each render
  console.log('Regular Count is: ' + regularVar); // Always reset to 0

  const increment = () => {
    setCount(count + 1);
    regularVar = regularVar + 1;
  };

  return (
    <>
      <h1>{count}</h1>
      <button onClick={increment}>Click</button>
    </>
  );
};

A re-render means that the component function is called again. This causes the log statements to be logged to the console. When this happens the regular JavaScript variable will be re-initialized to 0 while the React state variable will not.

React State and Scope

React state is also local to the component. This means that even if a component is created multiple times, each one will have its own state management. In the code below, each Counter component has its own count state.

import {useState} from 'react';

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

  const increment = () => {
    setCount(count + 1);
  };

  return (
    <>
      <h1>{count}</h1>
      <button onClick={increment}>Click</button>
    </>
  );
};

const App = () => {

  return (
    <>
      <Counter />
      <Counter />
    </>
  );
};

Clicking either Counter component's button doesn't affect the other's state. If we wanted these components to share state, we could move it to the parent component and pass it down as props.

import {useState} from 'react';

const Counter = (props) => {

  const increment = () => {
    props.setCount(props.count + 1);
  };

  return (
    <>
      <h1>{props.count}</h1>
      <button onClick={increment}>Click</button>
    </>
  );
};

const App = () => {
  const [count, setCount] = useState(0);

  return (
    <>
      <Counter count={count} setCount={setCount} />
      <Counter count={count} setCount={setCount} />
    </>
  );
};