How to Toggle a Boolean State in React

To toggle a boolean state in React:

  1. Use the useState hook create the boolean state (if you haven’t already).
  2. Pass a callback to the state updater function (setState).
  3. Return the negation of the boolean variable from the callback.

For example:

JavaScript
import { useState } from 'react'; export default function App() { const [visible, setVisible] = useState(false); const handleToggle = () => { setVisible((current) => !current); }; return ( <div> <button onClick={handleToggle}>Show name</button> {visible && <p>Coding Beauty</p>} </div> ); }
The text's visibility is toggled on button click
The text’s visibility is toggled on button click

We create the boolean state with the useState hook. useState returns an array of two values, the first is the value of the state, the second is a function that updates the state when it is called.

We pass a callback function to setVisible because the callback is always passed the latest visible state.

Tip: Always pass a function to setState when the new state is computed from the current state data.

In our case, the callback simply negates the boolean value and returns the result to negate the state.

The logical NOT (!) operator converts a truthy value to false and a falsy value to true.

JavaScript
console.log(!true); // false console.log(!false); // true console.log(!5); // false console.log(!undefined); // true

Note: In JavaScript there are only 6 falsy values: undefined, null, '' (empty string), NaN, 0, and false. Every other value is truthy and will result in false when negated.

Perform action on boolean state toggle

Sometimes you want to perform an action outside of re-rendering when the boolean state changes in the component, e.g., a network request. To carry out such an action, place the code in the useEffect hook and include the boolean state variable in useEffect‘s dependencies array.

JavaScript
import { useEffect, useState } from 'react'; import axios from 'axios'; export default function App() { const [visible, setVisible] = useState(false); const handleToggle = () => { setVisible((current) => !current); }; useEffect(() => { if (visible) { axios.post('https://example.com/stats/name/views').then(() => { console.log('Updated stats successfully.') }); } }, [visible]); return ( <div> <button onClick={handleToggle}>Show name</button> {visible && <p style={{ color: 'blue' }}>Coding Beauty</p>} </div> ); }

The code in the useEffect hook runs after the component mounts or updates from a change in the visible state. Here, the state controls the visibility of an element, so in the hook, we check if the element is visible, and if so, we make a network request to a server to update view stats associated with the element.

Perform action on boolean state change but skip first render

Depending on your scenario, you might want the action to run when the component updates from a state change, but not it when it first mounts.

We can do this by creating a ref flag variable having an initial value of false in the first render, and change its value to true for all subsequent renders.

JavaScript
import { useEffect, useRef, useState } from 'react'; import axios from 'axios'; export default function App() { const afterFirstRender = useRef(false); const [visible, setVisible] = useState(false); const handleToggle = () => { setVisible((current) => !current); }; useEffect(() => { if (!afterFirstRender.current) { afterFirstRender.current = true; return; } if (visible) { axios.post('https://example.com/stats/name/show').then(() => { console.log('Stats updated successfully') }); } }, [visible]); return ( <div> <button onClick={handleToggle}>Show name</button> {visible && <p style={{ color: 'blue' }}>Coding Beauty</p>} </div> ); }

useRef returns a mutable ref object that doesn’t change value when a component is updated. Also, modifying the value of this object’s current property does not cause a re-render. This is in contrast to the setState update function returned from useState.

If the ref’s value is false, we prevent the action from happening in useEffect and change the value to true for the following renders. Otherwise, we execute the action.



Every Crazy Thing JavaScript Does

A captivating guide to the subtle caveats and lesser-known parts of JavaScript.

Every Crazy Thing JavaScript Does

Sign up and receive a free copy immediately.

Leave a Comment

Your email address will not be published. Required fields are marked *