How to toggle a Boolean state in React

avatar
Borislav Hadzhiev

Last updated: Apr 7, 2024
3 min

banner

# Toggle a Boolean state in React

To toggle a boolean state in React:

  1. Use the useState hook to track the state of the boolean.
  2. Pass a function to the setState function the hook returns.
  3. Toggle the boolean based on the current value.
App.js
import {useState} from 'react'; export default function App() { // ๐Ÿ‘‡๏ธ Initialize boolean to false const [isLoading, setIsLoading] = useState(false); const toggleIsLoading = () => { // ๐Ÿ‘‡๏ธ Passed function to setState setIsLoading(current => !current); }; return ( <div> <button onClick={toggleIsLoading}>Toggle loading state</button> {isLoading && <h2>bobbyhadz.com...</h2>} </div> ); }

toggle boolean state

The code for this article is available on GitHub

We passed a function to setIsLoading because the function is guaranteed to be called with the current (most up-to-date) value for the isLoading boolean.

App.js
const toggleIsLoading = () => { // ๐Ÿ‘‡๏ธ passed function to setState setIsLoading(current => !current); };

In the example, we simply toggle the boolean and return the result to update the state.

We used the logical NOT (!) operator to flip the boolean value.

Here are some examples of using the logical NOT operator.

App.js
console.log(!true); // ๐Ÿ‘‰๏ธ false console.log(!false); // ๐Ÿ‘‰๏ธ true
Note that you shouldn't try to immediately access the boolean state variable after changing it.

If you try to access the isLoading state variable immediately after using the setIsLoading function to update it, there is no guarantee that you'll get the current (most up-to-date) value.

# Perform an action when boolean state changes in React

If you need to listen to state changes, add the state variables to the dependencies array of the useEffect hook.

App.js
import {useEffect, useState} from 'react'; export default function App() { const [isLoading, setIsLoading] = useState(false); const toggleIsLoading = () => { // ๐Ÿ‘‡๏ธ Passed function to setState setIsLoading(current => !current); }; useEffect(() => { // ๐Ÿ‘‡๏ธ If you need to listen for changes of isLoading boolean console.log('isLoading is: ', isLoading); }, [isLoading]); return ( <div> <button onClick={toggleIsLoading}>Toggle loading state</button> {isLoading && <h2>bobbyhadz.com...</h2>} </div> ); }

listen to changes of boolean state

The code for this article is available on GitHub

We added the isLoading state variable to the hook's dependencies array, so any time isLoading changes, the logic in our useEffect hook will rerun.

Note that the hook is also invoked when the component mounts.

Here is an example of how to toggle boolean state and make an HTTP request only when the state is equal to true.

App.js
import {useEffect, useState} from 'react'; export default function App() { const [isActive, setIsActive] = useState(false); const [data, setData] = useState({data: []}); const toggleIsActive = () => { setIsActive(isActive => !isActive); }; useEffect(() => { console.log('isActive is: ', isActive); if (isActive) { fetchData(); } else { setData({data: []}); } }, [isActive]); const fetchData = async () => { const response = await fetch('https://reqres.in/api/users', { method: 'GET', headers: {Accept: 'application/json'}, }); const result = await response.json(); console.log('result is: ', JSON.stringify(result, null, 4)); setData(result); }; return ( <div> <button onClick={toggleIsActive}> Toggle active state </button> {isActive && <h2>bobbyhadz.com...</h2>} {data.data.map(person => { return ( <div key={person.id}> <h2>{person.email}</h2> <h2>{person.first_name}</h2> <h2>{person.last_name}</h2> <br /> </div> ); })} </div> ); }

toggle boolean state perform action

The code for this article is available on GitHub

We used the useEffect hook to check if the boolean state is equal to true.

If it is, we fetch data from a remote API, otherwise, we set the data state to its initial value.

App.js
useEffect(() => { console.log('isActive is: ', isActive); if (isActive) { fetchData(); } else { setData({data: []}); } }, [isActive]);

When the state is toggled, the data is shown or hidden depending on if its value is true or false.

# Listen to changes of a boolean state but skip the first render

If you don't want to run the logic in your useEffect hook on the initial render, but only when the specific state variable changes, use a ref to return early on the initial render.

App.js
import {useEffect, useState, useRef} from 'react'; export default function App() { const [isLoading, setIsLoading] = useState(false); const toggleIsLoading = () => { setIsLoading(current => !current); }; const isFirstRender = useRef(true); useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; // ๐Ÿ‘ˆ๏ธ Return early if first render } console.log('isLoading is: ', isLoading); }, [isLoading]); return ( <div> <button onClick={toggleIsLoading}>Toggle loading state</button> {isLoading && <h2>bobbyhadz.com...</h2>} </div> ); }

perform action on boolean state change skip first render

The code for this article is available on GitHub

We used a ref to exit early when the useEffect hook is run on mount.

App.js
useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; // ๐Ÿ‘ˆ๏ธ Return early if first render } console.log('isLoading is: ', isLoading); }, [isLoading]);

If the ref's value is set to true, we return early from useEffect and set the ref's value to false.

The next time the useEffect hook runs, the ref's value is set to false and the remainder of the hook runs.

Use this approach if you want to listen for state changes but need to skip the first render.

I've also written an article on how to render a boolean in JSX.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev