useCssVar (React)
Set, get and remove a
CSS custom property
from the comfort of a React component. This could result in slightly more
performant code when you're setting the style
property directly since React
will re-run your component fewer times.
import { useMemo, useEffect } from 'react'type UseCssVarProps = { name: string root?: HTMLElement}type CssVarControls = { set: (value: string) => void get: () => string remove: () => void}export const useCssVar = ({ name, root = document.body,}: UseCssVarProps): CssVarControls => { const controls: CssVarControls = useMemo( () => ({ set: value => root.style.setProperty(name, value), get: () => root.style.getPropertyValue(name), remove: () => root.style.removeProperty(name), }), [name, root] ) useEffect(() => { return () => controls.remove() }, [controls]) return controls}
Info
-
We use
useMemo
, so that if you follow hook rules and use the helpers in a function inside auseEffect
,useCallback
, etc, you won't have code (re-)running unnecessarily. -
If you don't want the variable to be removed when the hook is no longer used, you can either remove the
useEffect
, or add an extra prop and conditionally return a cleanup function in theuseEffect
. -
This hook doesn't use
useState
since it would nullify the performance aspect, and I didn't feel the need to be notified when the variable changed on the root. You could useMutationObserver
if you wanted to know if the variable was updated on theroot
.
Demo
If you open up your browser's devtools, find the <main>
element and look at
its style
attribute, you'll see the --example-css-var
CSS
variable change as you change the input's value or press the button.
The image's rotation is handled by styling it with transform:
rotate(calc(var(--example-css-var, 45) * 1deg))
.