Skip to content

Instantly share code, notes, and snippets.

@jqn
Forked from gragland/use-toggle.jsx
Created January 14, 2021 13:47
Show Gist options
  • Save jqn/acf07f030f2fc6439f00990d1beb8827 to your computer and use it in GitHub Desktop.
Save jqn/acf07f030f2fc6439f00990d1beb8827 to your computer and use it in GitHub Desktop.
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];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment