MT IT
  • Introduction
  • KEEP IN MIND!!
  • 1️⃣1st month
    • Week 1
      • HTML/CSS
        • HTML
          • HTML Dasar
          • HTML Layouting
          • Learn More
            • Semantic HTML
            • Tables
            • Videos
            • Images
        • CSS
          • CSS Dasar
      • Weekly Review
    • Week 2
      • Bootstrap
        • Tutorial Bootstrap 5
      • Git & Github
      • Responsive
        • Responsive with Bootstrap 5
      • Weekly Review
    • Week 3
      • Javascript
        • Introduction to Javascript
          • What is JavaScript?
          • Brief History of JavaScript
          • How To Add JavaScript to HTML
        • All About Variables
          • Variables
          • Naming JavaScript Variables
          • JavaScript Naming Conventions
          • JavaScript Scope
        • Datatypes
          • What are data types?
          • Primitives and objects
          • Primitive data types
          • Object data types
          • TypeOf Operator
      • Weekly Review
    • Week 4
      • Javascript
        • Data Structures
          • Keyed Collections
          • Indexed collections
        • Equality Comparisons
        • Loops and Iterations
          • The for loop
          • do…while statement
          • while statement
      • Weekly Review
    • Monthly Review
  • 2️⃣2nd Month
    • Week 5
      • Javascript
        • Expressions and Operators
          • Basic operators, maths
          • Assignment operators
          • Comparison operators
          • Logical operators
          • String operators
          • Conditional (ternary) operator
          • Comma operator
        • JavaScript Function
        • Arrow function expressions
        • Built in functions
      • REST - Representational State Transfer
        • API - Application Programming Interface
        • Fetching data from the server
        • The Fetch API
        • Cross-Origin Resource Sharing (CORS)
      • Weekly Review
    • Week 6
      • DOM (Document Object Model)
        • DOM tree
        • Selecting elements
          • getElementById()
          • getElementsByName()
          • querySelector()
        • Manipulating elements
          • createElement()
          • appendChild()
          • textContent
        • Working with Attributes
          • Understanding Relationships Between HTML Attributes & DOM Object’s Properties
          • setAttribute()
          • getAttribute()
          • removeAttribute()
          • hasAttribute()
        • Manipulating Element’s Styles
          • JavaScript Style
          • getComputedStyle()
          • className
          • classList
          • Getting the Width and Height of an Element
        • Working with Events
          • JavaScript Events
          • Handling Events
          • Page Load Events
          • onload
          • Mouse Events
          • Keyboard Events
          • Scroll Events
          • scrollIntoView
      • React JS
        • Getting Started
        • Components Basics
          • Introducing JSX
          • Writing Markup with JSX
          • React Function Components
          • Props vs State
            • State: A Component's Memory
            • How to use Props in React
      • Working with APIs - 1
        • XMLHttpRequest
        • Fetch
      • Weekly Review
    • Week 7
      • Javascript
        • Asynchronous JavaScript
          • Asynchronous JavaScript For Dummies
            • (Pt1): Internals Disclosed!
            • (Pt2): Callbacks
            • (Pt3): Promises
            • (Pt4): Async/Await
        • Callback
        • Promises
          • Promises Basics
          • Promises Chaining
          • Promises Error Handling
        • Async/await
          • async function
        • Tutorial – Learn Callbacks, Promises, & Async/Await in JS by Making Ice Cream
      • React JS
        • Rendering
          • Conditional Rendering
          • Lists and Keys
          • Render Props
        • Hooks
          • useState
          • useEffect
      • Working with APIs - 2
        • Axios
      • React Router Dom
      • Weekly Review
    • Week 8
      • React JS
      • Responsive
      • Chakra UI
      • Firebase
        • Firebase Authentication
      • Weekly Review
    • Monthly Review
  • 3️⃣3rd month
    • Week 9
      • React JS
      • Chakra UI
      • Firebase
      • Axios
      • Weekly Review
    • Week 10
      • React JS
      • Boilerplate
      • Weekly Review
    • Week 11
      • Projects
      • Weekly Review
    • Week 12
      • Projects
      • Weekly Review
    • Project Review
  • 🏁FINAL REVIEW
  • 👇!! Learn More Below !!
  • 🥸Frontend Stack
    • 💻Web Dev
      • React JS
        • Reactstrap
        • React Icons
        • React Router Dom
      • Chakra UI
    • 📱Mobile Dev
      • React Native
        • Introduction
        • Page 1
      • Expo
      • Nativebase
    • 🎽CSS
      • Tailwind
      • Bootstrap
  • ☕Backend Stack
    • Node JS
    • Firebase
      • Authentication
      • Firestore
      • Storage
      • Hosting
      • Cloud Function
      • Emulators
      • RTDB
      • FCM
    • Google Cloud Platform
      • AppEngine
      • Big Query
      • Cloud Functions
      • Cloud Run
      • Cloud Scheduler
      • Cloud SQL
      • Logging
    • Object Relational Mapping (ORM)
      • Sequelize
    • MongoDB
      • MongoDB Realm
    • MySQL
      • Introduction
  • 🦸Fullstack
    • NEXT JS
    • LARAVEL
  • 📦Package
    • Middleware
      • Express JS
    • HTTP client
      • AXIOS
    • 📊Chart
      • Chart.js
      • JSCharting
      • React Google Chart
    • ⏳Date & Time
      • Moment JS
      • Day JS
    • 👨‍💻WYSIWYG Editor
      • Quill JS
      • Slate JS
Powered by GitBook
On this page
  • Usage
  • Troubleshooting
  • SIMPLE STATE IN REACT
  • COMPLEX STATE IN REACT
  • ASYNCHRONOUS STATE IN REACT
  1. 2nd Month
  2. Week 7
  3. React JS
  4. Hooks

useState

useState is a React Hook that lets you add a state variable to your component. const [state, setState] = useState(initialState);

PreviousHooksNextuseEffect

Last updated 1 year ago

useState(initialState)

Call useState at the top level of your component to declare a

import { useState } from 'react';

function MyComponent() {
  const [age, setAge] = useState(28);
  const [name, setName] = useState('Taylor');
  const [todos, setTodos] = useState(() => createTodos());
  // ...

The convention is to name state variables like [something, setSomething] using

Parameters

  • initialState: The value you want the state to be initially. It can be a value of any type, but there is a special behavior for functions. This argument is ignored after the initial render.

    • If you pass a function as initialState, it will be treated as an initializer function. It should be pure, should take no arguments, and should return a value of any type. React will call your initializer function when initializing the component, and store its return value as the initial state.

Returns

useState returns an array with exactly two values:

  1. The current state. During the first render, it will match the initialState you have passed.

  2. The that lets you update the state to a different value and trigger a re-render.

Caveats

  • useState is a Hook, so you can only call it at the top level of your component or your own Hooks. You can’t call it inside loops or conditions. If you need that, extract a new component and move the state into it.


set functions, like setSomething(nextState)

The set function returned by useState lets you update the state to a different value and trigger a re-render. You can pass the next state directly, or a function that calculates it from the previous state:

const [name, setName] = useState('Edward');

function handleClick() {
  setName('Taylor');
  setAge(a => a + 1);
  // ...

Parameters

  • nextState: The value that you want the state to be. It can be a value of any type, but there is a special behavior for functions.

Returns

set functions do not have a return value.

Caveats


Usage

Adding state to a component

import { useState } from 'react';

function MyComponent() {
  const [age, setAge] = useState(42);
  const [name, setName] = useState('Taylor');
  // ...

useState returns an array with exactly two items:

  1. The current state of this state variable, initially set to the initial state you provided.

  2. The set function that lets you change it to any other value in response to interaction.

To update what’s on the screen, call the set function with some next state:

function handleClick() {
  setName('Robin');
}

React will store the next state, render your component again with the new values, and update the UI.

Pitfall

function handleClick() {
  setName('Robin');
  console.log(name); // Still "Taylor"!
}

It only affects what useState will return starting from the next render.

Updating state based on the previous state

Suppose the age is 42. This handler calls setAge(age + 1) three times:

function handleClick() {
  setAge(age + 1); // setAge(42 + 1)
  setAge(age + 1); // setAge(42 + 1)
  setAge(age + 1); // setAge(42 + 1)
}

To solve this problem, you may pass an updater function to setAge instead of the next state:

function handleClick() {
  setAge(a => a + 1); // setAge(42 => 43)
  setAge(a => a + 1); // setAge(43 => 44)
  setAge(a => a + 1); // setAge(44 => 45)
}

Here, a => a + 1 is your updater function. It takes the pending state and calculates the next state from it.

  1. a => a + 1 will receive 42 as the pending state and return 43 as the next state.

  2. a => a + 1 will receive 43 as the pending state and return 44 as the next state.

  3. a => a + 1 will receive 44 as the pending state and return 45 as the next state.

There are no other queued updates, so React will store 45 as the current state in the end.

By convention, it’s common to name the pending state argument for the first letter of the state variable name, like a for age. However, you may also call it like prevAge or something else that you find clearer.

Updating objects and arrays in state

You can put objects and arrays into state. In React, state is considered read-only, so you should replace it rather than mutate your existing objects. For example, if you have a form object in state, don’t mutate it:

// 🚩 Don't mutate an object in state like this:
form.firstName = 'Taylor';

Instead, replace the whole object by creating a new one:

// ✅ Replace state with a new object
setForm({reac
  ...form,
  firstName: 'Taylor'
});

Avoiding recreating the initial state

React saves the initial state once and ignores it on the next renders.

function TodoList() {
  const [todos, setTodos] = useState(createInitialTodos());
  // ...

Although the result of createInitialTodos() is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating large arrays or performing expensive calculations.

To solve this, you may pass it as an initializer function to useState instead:

function TodoList() {
  const [todos, setTodos] = useState(createInitialTodos);
  // ...

Notice that you’re passing createInitialTodos, which is the function itself, and not createInitialTodos(), which is the result of calling it. If you pass a function to useState, React will only call it during initialization.

Resetting state with a key

You can reset a component’s state by passing a different key to a component. In this example, the Reset button changes the version state variable, which we pass as a key to the Form. When the key changes, React re-creates the Form component (and all of its children) from scratch, so its state gets reset.

Storing information from previous renders

Usually, you will update state in event handlers. However, in rare cases you might want to adjust state in response to rendering — for example, you might want to change a state variable when a prop changes.

In most cases, you don’t need this:

  • If you can, update all the relevant state in the event handlers.

In the rare case that none of these apply, there is a pattern you can use to update state based on the values that have been rendered so far, by calling a set function while your component is rendering.

Here’s an example. This CountLabel component displays the count prop passed to it:

export default function CountLabel({ count }) {
  return <h1>{count}</h1>
}

Say you want to show whether the counter has increased or decreased since the last change. The count prop doesn’t tell you this — you need to keep track of its previous value. Add the prevCount state variable to track it. Add another state variable called trend to hold whether the count has increased or decreased. Compare prevCount with count, and if they’re not equal, update both prevCount and trend. Now you can show both the current count prop and how it has changed since the last render.

This pattern can be hard to understand and is usually best avoided. However, it’s better than updating state in an effect. When you call the set function during render, React will re-render that component immediately after your component exits with a return statement, and before rendering the children. This way, children don’t need to render twice. The rest of your component function will still execute (and the result will be thrown away). If your condition is below all the Hook calls, you may add an early return; to restart rendering earlier.


Troubleshooting

I’ve updated the state, but logging gives me the old value

Calling the set function does not change state in the running code:

function handleClick() {
  console.log(count);  // 0

  setCount(count + 1); // Request a re-render with 1
  console.log(count);  // Still 0!

  setTimeout(() => {
    console.log(count); // Also 0!
  }, 5000);
}

If you need to use the next state, you can save it in a variable before passing it to the set function:

const nextCount = count + 1;
setCount(nextCount);

console.log(count);     // 0
console.log(nextCount); // 1

I’ve updated the state, but the screen doesn’t update

obj.x = 10;  // 🚩 Wrong: mutating existing object
setObj(obj); // 🚩 Doesn't do anything
// ✅ Correct: creating a new object
setObj({
  ...obj,
  x: 10
});

I’m getting an error: “Too many re-renders”

You might get an error that says: Too many re-renders. React limits the number of renders to prevent an infinite loop. Typically, this means that you’re unconditionally setting state during render, so your component enters a loop: render, set state (which causes a render), render, set state (which causes a render), and so on. Very often, this is caused by a mistake in specifying an event handler:

// 🚩 Wrong: calls the handler during render
return <button onClick={handleClick()}>Click me</button>

// ✅ Correct: passes down the event handler
return <button onClick={handleClick}>Click me</button>

// ✅ Correct: passes down an inline function
return <button onClick={(e) => handleClick(e)}>Click me</button>

If you can’t find the cause of this error, click on the arrow next to the error in the console and look through the JavaScript stack to find the specific set function call responsible for the error.


My initializer or updater function runs twice

function TodoList() {
  // This component function will run twice for every render.

  const [todos, setTodos] = useState(() => {
    // This initializer function will run twice during initialization.
    return createTodos();
  });

  function handleClick() {
    setTodos(prevTodos => {
      // This updater function will run twice for every click.
      return [...prevTodos, createTodo()];
    });
  }
  // ...

This is expected and shouldn’t break your code.

For example, this impure updater function mutates an array in state:

setTodos(prevTodos => {
  // 🚩 Mistake: mutating state
  prevTodos.push(createTodo());
});
setTodos(prevTodos => {
  // ✅ Correct: replacing with new state
  return [...prevTodos, createTodo()];
});

Now that this updater function is pure, calling it an extra time doesn’t make a difference in behavior. This is why React calling it twice helps you find mistakes. Only component, initializer, and updater functions need to be pure. Event handlers don’t need to be pure, so React will never call your event handlers twice.


I’m trying to set state to a function, but it gets called instead

You can’t put a function into state like this:

const [fn, setFn] = useState(someFunction);

function handleClick() {
  setFn(someOtherFunction);
}
const [fn, setFn] = useState(() => someFunction);

function handleClick() {
  setFn(() => someOtherFunction);
}

<=======================================================================>

SIMPLE STATE IN REACT

In the past, state couldn't be used in function components. Hence they called them functional stateless components. However, with the release of React Hooks, state can be used in this kind of component too, and so they were rebranded by the React community to function components. A straightforward example on how to use state in a function component with the useState hook is demonstrated in the following example:

const App = () => {
  const [count, setCount] = React.useState(0);
  const handleIncrease = () => {
    setCount(count + 1);
  };
  const handleDecrease = () => {
    setCount(count - 1);
  };
  return (
    <div>
      {" "}
      Count: {count} <hr />{" "}
      <div>
        {" "}
        <button type="button" onClick={handleIncrease}>
          {" "}
          Increase{" "}
        </button>{" "}
        <button type="button" onClick={handleDecrease}>
          {" "}
          Decrease{" "}
        </button>{" "}
      </div>{" "}
    </div>
  );
};

The first value, in this case count, represents the current state. The second value, in this case setCount, is a function to update the state with anything that's passed to this function when calling it. This function is also called the state update function. Every time this function is called, React re-renders the component to render the new state.

That's everything you need to know to get started with simple state management in React. If you are interested about React's useState caveats for growing React applications, then continue to read.

COMPLEX STATE IN REACT

  • complex state containers

  • complex state transitions

  • conditional state updates

It also helps to avoid multiple successive state updates by using only useState. You should definitely check it out if you want to manage more complex state in React.

ASYNCHRONOUS STATE IN REACT

const App = () => {
  const [count, setCount] = React.useState(0);
  const handleIncrease = () => {
    setTimeout(() => setCount(count + 1), 1000);
  };
  const handleDecrease = () => {
    setTimeout(() => setCount(count - 1), 1000);
  };
  return (
    <div>
      {" "}
      Count: {count} <hr />{" "}
      <div>
        {" "}
        <button type="button" onClick={handleIncrease}>
          {" "}
          Increase{" "}
        </button>{" "}
        <button type="button" onClick={handleDecrease}>
          {" "}
          Decrease{" "}
        </button>{" "}
      </div>{" "}
    </div>
  );
};

Every time you click on one of the buttons, the state update function is called with a delay of one second. That works for a single click. However, try to click one of the buttons multiple times in a row. The state update function will always operate on the same state (here: count) within this one second. In order to fix this problem, you can pass a function to the state update function from useState:

import React from "react";
const App = () => {
  const [count, setCount] = React.useState(0);
  const handleIncrease = () => {
    setTimeout(() => setCount((state) => state + 1), 1000);
  };
  const handleDecrease = () => {
    setTimeout(() => setCount((state) => state - 1), 1000);
  };
  return (
    <div>
      {" "}
      Count: {count} <hr />{" "}
      <div>
        {" "}
        <button type="button" onClick={handleIncrease}>
          {" "}
          Increase{" "}
        </button>{" "}
        <button type="button" onClick={handleDecrease}>
          {" "}
          Decrease{" "}
        </button>{" "}
      </div>{" "}
    </div>
  );
};
export default App;

The function offers you the state at the time of executing the function. This way, you never operate on any stale state. Therefore, a good rule of thumb may be: always use a function in useState's update function if your state update depends on your previous state.


In Strict Mode, React will call your initializer function twice in order to This is development-only behavior and does not affect production. If your initializer function is pure (as it should be), this should not affect the behavior. The result from one of the calls will be ignored.

If you pass a function as nextState, it will be treated as an updater function. It must be pure, should take the pending state as its only argument, and should return the next state. React will put your updater function in a queue and re-render your component. During the next render, React will calculate the next state by applying all of the queued updaters to the previous state.

The set function only updates the state variable for the next render. If you read the state variable after calling the set function, that was on the screen before your call.

If the new value you provide is identical to the current state, as determined by an comparison, React will skip re-rendering the component and its children. This is an optimization. Although in some cases React may still need to call your component before skipping the children, it shouldn’t affect your code.

React It updates the screen after all the event handlers have run and have called their set functions. This prevents multiple re-renders during a single event. In the rare case that you need to force React to update the screen earlier, for example to access the DOM, you can use

Calling the set function during rendering is only allowed from within the currently rendering component. React will discard its output and immediately attempt to render it again with the new state. This pattern is rarely needed, but you can use it to store information from the previous renders.

In Strict Mode, React will call your updater function twice in order to This is development-only behavior and does not affect production. If your updater function is pure (as it should be), this should not affect the behavior. The result from one of the calls will be ignored.

Call useState at the top level of your component to declare one or more

The convention is to name state variables like [something, setSomething] using

Calling the set function :

However, after one click, age will only be 43 rather than 45! This is because calling the set function the age state variable in the already running code. So each setAge(age + 1) call becomes setAge(43).

React puts your updater functions in a Then, during the next render, it will call them in the same order:

React may in development to verify that they are

Read and to learn more.

React may in development to verify that they are

You’ll often encounter the key attribute when However, it also serves another purpose.

Read to learn more.

If the value you need can be computed entirely from the current props or other state, If you’re worried about recomputing too often, the can help.

If you want to reset the entire component tree’s state,

Note that if you call a set function while rendering, it must be inside a condition like prevCount !== count, and there must be a call like setPrevCount(count) inside of the condition. Otherwise, your component would re-render in a loop until it crashes. Also, you can only update the state of the currently rendering component like this. Calling the set function of another component during rendering is an error. Finally, your set call should still — this doesn’t mean you can break other rules of

This is because Updating state requests another render with the new state value, but does not affect the count JavaScript variable in your already-running event handler.

React will ignore your update if the next state is equal to the previous state, as determined by an comparison. This usually happens when you change an object or an array in state directly:

You mutated an existing obj object and passed it back to setObj, so React ignored the update. To fix this, you need to ensure that you’re always :

In , React will call some of your functions twice instead of once:

This development-only behavior helps you React uses the result of one of the calls, and ignores the result of the other call. As long as your component, initializer, and updater functions are pure, this shouldn’t affect your logic. However, if they are accidentally impure, this helps you notice the mistakes.

Because React calls your updater function twice, you’ll see the todo was added twice, so you’ll know that there is a mistake. In this example, you can fix the mistake by :

Read to learn more.

Because you’re passing a function, React assumes that someFunction is an , and that someOtherFunction is an , so it tries to call them and store the result. To actually store a function, you have to put () => before them in both cases. Then React will store the functions you pass.

The useState function takes as argument a value for the initial state. In this case, the count starts at 0. In addition, the hook returns an array of two values: count and setCount. It's up to you to name the two values, because they are where renaming is allowed.

You can also read this in case you are dealing with class components as well.

So far, the example has only shown useState with a JavaScript primitive. That's where useState shines. It can be used for integers, booleans, strings, and also arrays. However, once you plan to manage more complex state with objects or more complex arrays, you should check out . There are various scenarios where useReducer outperforms useState:

What happens if you are dependent on actual state to update the state? Let's illustrate this case with an example where we are delaying the state update with a function:

React's useState is the go-to hook to manage state. It can be used for modern state management in React.

2️⃣
state variable.
array destructuring.
See more examples below.
See an example below.
set function
help you find accidental impurities.
See an example below.
you will still get the old value
Object.is
batches state updates.
flushSync.
See an example below.
help you find accidental impurities.
state variables.
array destructuring.
does not change the current state in the already executing code
does not update
queue.
call your updaters twice
pure.
updating objects in state
updating arrays in state
call your initializers twice
pure.
rendering lists.
preserving and resetting state
remove that redundant state altogether.
useMemo Hook
pass a different key to your component.
update state without mutation
pure functions.
states behaves like a snapshot.
Object.is
replacing objects and arrays in state instead of mutating them
Strict Mode
keep components pure.
replacing the array instead of mutating it
keeping components pure
initializer function
updater function
destructured from the returned array
article, if you want to know how state management has changed from class components to function components
React's useReducer hook
JavaScript built-in setTimeout
with useReducer and useContext
Compared to useReducer, it is the more lightweight approach to manage state.