Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Thought process when creating a useToggle() React hook with useState
import { useState, useCallback } from "react";
function useToggle(initialValue = false){
// State with initial boolean value (true/false)
const [state, setState] = useState(initialValue);
// Let's create a toggle function
// This works, but we're using the state value from above
// instead of the current state. Usually they are the same,
// but if this hook was triggered multiple times rapidly then
// state value above might actually be stale.
const toggle = () => setState(!state);
// Okay, problem solved. We're now using the function argument format
// of useState so that we're always reading the current state.
// But we have another problem. We're creating a new function on every render.
// The concern isn't that creating new function is expensive,
// but rather that if toggle() gets passed to child components it could
// cause them to re-render if the function is new every time.
const toggle = () => setState((currentState) => !currentState);
// No problem. That's what useCallback is for.
// Our toggle function is now only created once on mount. Hurray 🎉
const toggle = useCallback(() => setState((currentState) => !currentState), []);
return [state, toggle];
}
@elisechant

This comment has been minimized.

Copy link

@elisechant elisechant commented Jan 10, 2021

Nice

@adrianlee

This comment has been minimized.

Copy link

@adrianlee adrianlee commented Jan 31, 2021

Thanks for this!

@vjau

This comment has been minimized.

Copy link

@vjau vjau commented Feb 12, 2021

Didn't know about useCallback, thanks.

@adisa-di

This comment has been minimized.

Copy link

@adisa-di adisa-di commented Feb 20, 2021

This is cool - thanks 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment