Normalizes initializer function (some hook providers have it not implemented).
Takes optional deps to reinitialize state.
function MyComponent(props) {
// sets `currentValue` to `value` whenever passed `props.value` changes.
let [currentValue, setCurrentValue] = useState(props.value, [props.value])
}
useEffect(fn, deps?)
Guarantees microtask - react/preact unpredictably call as microtask or sync.
No-deps useEffect(fn) is the same as empty-deps useEffect(fn, []).
React's useEffect(fn) is equivalent to queueMicrotask(fn), which is redundant hook (principle 3).
That is compatible with useState(initFn) (principle 2).
Single-run useEffect(fn) is equivalent to useInit(fn)/useMount(fn) − that reduces cognitive load / lib size (principle 1).
Supports async functions.
Ignores non-functional returns.
function MyComponent(props) {
let [result, setResult] = useState()
// called once on init
useEffect(async () => setResult(await load('/data')))
// ...
}
Arguments against
That's matter of diversity vs unification.
useEffect(() => () => {}) can be useful to destroy/reinit effect, that is not the same as queueMicrotask.
useState() can be replaced with useMemo(calc, deps) to provide deps.
useInit() is something closer to sync effect, rather than microtask.
useState(init?, deps?)
deps
to reinitialize state.useEffect(fn, deps?)
useEffect(fn)
is the same as empty-depsuseEffect(fn, [])
.useEffect(fn)
is equivalent toqueueMicrotask(fn)
, which is redundant hook (principle 3).useState(initFn)
(principle 2).useEffect(fn)
is equivalent touseInit(fn)
/useMount(fn)
− that reduces cognitive load / lib size (principle 1).Arguments against
That's matter of diversity vs unification.
useEffect(() => () => {})
can be useful to destroy/reinit effect, that is not the same asqueueMicrotask
.useState()
can be replaced withuseMemo(calc, deps)
to provide deps.useInit()
is something closer to sync effect, rather than microtask.