ReactJS | useState Hook

Functional components are some of the more commonly used components in ReactJS. Most developers prefer using functional components over class-based components for the simple reason that functional components require less coding (on the developer’s part). However, two main features for the class are lost when one goes with a functional component – a dedicated state which persists through render calls as well as the use of lifecycle functions to control how the component looks and behaves at separate stages of its lifecycle.

Since version 16.8, a new feature called hooks was added to ReactJS which exposed the various features of class-based components. The two most used hooks are the useState() hook, which allows functional components to have a dedicated state of their own, and the useEffect() hook, which allows functional components to manipulate DOM elements before each render (almost like one gets to do it in lifecycle functions).

useState() hook allows one to declare a state variable inside a function. It should be noted that one use of useState() can only be used to declare one state variable.

Example: Program to demonstrate the basic use of useState() hook.

filter_none

edit
close

play_arrow

link
brightness_4
code

import React, { useState } from 'react';
  
function basicState() {
  const click = useState('GeeksForGeeks');
  return (
    <h1>Welcome to {click}</h1>
  );
}
  
export default basicState;

chevron_right


Output:



The value returned by useState() consists of an array with two values. The first value is the initial (or starting) value of the state variable, while the second value is a reference to the function that can be used to update the variable. One can always use array destructuring to assign both values at once so that they can be used in the component. Of course, they can also be assigned separately by assigning a variable with useState() and assigning its first index to one variable and its second index to another (destructuring just makes this easier).

Example: Program to demonstrate the use of a state variable in a functional component and how to update it accordingly.

filter_none

edit
close

play_arrow

link
brightness_4
code

import React, { useState } from 'react';
  
function deReference() {
  const [click, setClick] = useState(0); 
 // using array destructuring here 
 // to assign initial value 0
 // to click and a reference to the function 
 // that updates click to setClick
  return (
    <div>
        
<p>You clicked {click} times</p>
  
      <button onClick={() => setClick(click + 1)}>
        Click me
      </button>
    </div>
  );
}
  
export default deReference;

chevron_right


Output:

The working of useState() might seem weird at first. After all, with every render, the function being rendered is a new one – how does the ‘state’ persist then? Behind the scenes, there’s an object representing the functional component in the memory, which has a stack of its own. Whenever the useState() hook is used, the value of the state variable is changed and the new variable is stored in a new cell in the stack. The stack pointer is incremented simultaneously to point towards the last cell. The value pointed to by this stack pointer is used after every render. On a deliberate refresh from the user, the stack is dumped, and a fresh allocation in the memory is done when the component is rendered.

Example: Program to demonstrate the use of last value while updating the value of the ‘state’ variable.

filter_none

edit
close

play_arrow

link
brightness_4
code

import React, { useState } from 'react';
  
function lastValue() {
  const [click, setClick] = useState(0);
    
  
  return (
    <div>
        
<p>You've clicked {click} times!</p>
  
        
<p>The number of times you have clicked
 is {click%2==0?'even!':'odd!'}</p>
  
      <button onClick={() => setClick(click => click + 1)}>
        Click me
      </button>
    </div>
  );
}
  
export default lastValue;

chevron_right


Output:

Note that in the above example, we are using an arrow function inside setClick() that fetches the previous value of click and uses it to update it with the new value. This form is useful in cases where it is necessary to perform data manipulations based on the value of the state variable. Passing a function is also useful in cases where one of the older values from the stack is captured and changed instead of the most recent value.

State variables can be arrays too. This is especially useful when one needs to deal with multiple values without finding the need to declare multiple state variables using useState().



Example: Program to demonstrate the use of arrays as a state variable (using useState()).

filter_none

edit
close

play_arrow

link
brightness_4
code

import React, { useState } from 'react';
  
  
function ArrayExample() {
  const [click, setClick] = useState([]);
    
  const addNumber = () => {
    setClick([
      ...click,
      {
        id: click.length,
        value: Math.random() * 10
      }
    ]);
  };
    
  
  return (
    <div>
      <ul>
       {click.map(item => (
          <li key={item.id}>{item.value}</li>
       ))}
      </ul>
      <button onClick={addNumber}>
        Click me
      </button>
    </div>
  );
}
  
export default ArrayExample;

chevron_right


Output:

useState() works differently from the setState() function (which is used to change the value of state variables in class-based components) when it comes to using arrays. setClick() does not merge new values with the existing ones on being called, it simply overwrites them with the new value. Hence, it is necessary to find a workaround for appending the existing values, which is done inside the addNumber() internal function with the help of the spread operator. The function creates a new variable with a certain id and value and adds it to the existing array (whose values are copied into the function using the spread operator).

If one needs to deal with multiple types of data at once, the best way to go for is with an object. While the same work can be done with separate state variables, objects make work much more efficient in the long run (also one can make do with fewer useState() declarations).

Example: Program to demonstrate the use of objects as a state variable (using useState()).

filter_none

edit
close

play_arrow

link
brightness_4
code

import React, { useState } from 'react';
  
function ObjectExample() {
  const [data, setData] = useState({
    username: '',
    password: ''
  });
  const [form, setForm] = useState({
    username: '',
    password: ''
  });
  const [submit, submitted] = useState(false);
  
  const printValues = e => {
    e.preventDefault();
    setForm({
      username: data.username,
      password: data.password
    });
    submitted(true);
  };
  
  const updateField = e => {
    setData({
      ...data,
      [e.target.name]: e.target.value
    });
  };
  
  return (
    <div>
    <form onSubmit={printValues}>
      <label>
        Username:
        <input
          value={data.username}
          name="username"
          onChange={updateField}
        />
      </label>
      <br />
      <label>
        Password:
        <input
          value={data.password}
          name="password"
          type="password"
          onChange={updateField}
        />
      </label>
      <br />
      <button>Submit</button>
    </form>
      
<p>{submit?form.username:null}</p>
  
      
<p>{submit?form.password:null}</p>
  
  </div>
  );
}
  
export default ObjectExample;

chevron_right


Output:

In the above example, the ‘data’ variable is used to temporarily store the entered values for the username and password fields. The spread operator is used again, to copy the existing value of the fields and update it accordingly. The ‘form’ variable is used to store the value of the values submitted through the form used in the component – which is then displayed below the form. Note that the spread operator isn’t used with setForm() while updating the ‘form’ state variable for the simple reason that one does not need to be bothered about the previously submitted values of the username and password fields.

react-js-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.