Playing with React over the weekend, I made a hook that’s like useState
except instead of returning a setter function it returns a component you can render:
function usePercentageSlider(label, initialValue) {
const [value, setValue] = useState(initialValue);
return [
value,
<div>
<div>
{label} {value}:
</div>
<div>
<input
type="range"
value={value}
onChange={(e) => setValue(e.target.value)}
min="0"
max="1"
step="0.01"
/>
</div>
</div>,
];
}
The idea is that the only way to set the value of foo
is via the UI component fooSlider
:
function App() {
const [foo, fooSlider] = usePercentageSlider("foo slider", 0);
return (
<div>
{fooSlider}
<h1>{foo}</h1>
</div>
);
}
This avoids the pattern where you define const [state, setState] = useState();
at
the top of a component then pass both the value and its setter to a child component like
<Picker state={state} onChange={setState} />
. But I’m a bit wary because it feels like
the sort of thing that is convenient at the expense of composability.
What would you say if you saw this in a code review? I'd love to hear any thoughts on this — I'm @noahlt on Twitter or you can email me at [email protected].