use Css Var (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
}
const defaultRoot = typeof document !== 'undefined' ? document.body : undefined
export const useCssVar = ({
name,
root = defaultRoot!,
}: 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
}import { useMemo, useEffect } from 'react'
const defaultRoot = typeof document !== 'undefined' ? document.body : undefined
export const useCssVar = ({ name, root = defaultRoot }) => {
const controls = 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
useStatesince 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 useMutationObserverif 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)).