use_effect lacks documentation
ydirson opened this issue · comments
This is about: Undocumented code
Problem
use_effect
is introduced in the tutorial and described in the API doc, with a new example.
About its role the doc says "used for hooking into the component’s lifecycle", which is very vague: what does this sentence add to "called every time after the component’s render has finished"?
The doc only says "The callback is called every time after the component’s render has finished."
OTOH we see that in both examples the callback itself returns a callback, but nothing is said about this callback and when it gets called. Only a "tip" saying "The callback can return [()] if there is no destructor to run." hints that there it is likely a destructor (intended for what?). The examples themselves do not make it any more clear.
Do you have any ideas on what the documentation should be? I would be happy to look at any PRs updating the docs
Do you have any ideas on what the documentation should be? I would be happy to look at any PRs updating the docs
I would be happy to reach the level of understanding where I can submit doc PRs, but as you can see from this ticket I will need help to get there, and I expected answers to my questions would be part of that. What follows come from the small level of insights I could get, and as you see it brings additional questions.
With a bit of step back, but without having still assimilated the whole stuff, my impression a lot of terminology about hooks is confusing, for example:
- "hook" is a very general programming concept, usually used to give the ability to run custom code at well-defined points of a framework code. The "Hooks are functions that let you store state and perform side effects" description does not seem to fit this too well: what are the points where we're hooking our custom code? I personally also do not understand what this
use_
prefix should evoke - "let you store state and perform side effects" looks interesting at first sight, until we see that one of them is named
use_state
(This hook is used to manage state in a function component, so ot must be half of the hooks?), another is nameduse_effect
(used for hooking into the component’s lifecycle and creating side effects. so not only it takes the other half of the roles of hooks, but it also hook into the component’s lifecycle, which kind of bring us back to the notion of "hook")
From what I gathered, I'd think that a few renamings could help newcomers greatly, eg.:
use_state
->state_simplevalue
use_reducer
->state_accumulator
(state_reducer
could likely talk to people coming with a functional-language background, but I feel the proximity withreduce()
is not really that much significant, and the construct does look like something that accumulates updates). That could also help to explain thatstate_simplevalue
is a special case of astate_accumulator
that just throws away the state it previously held (this explanation, plus personal experimentation after it, was instrumental in unlocking my understanding of those two hooks, it should be made much more clear early on). Also itsdispatch()
method seems to imply it will pass itsAction
to other actors, where from what I gathered all it is allowed to do is modify its internal state from the action - maybe something likeprocess(action)
would cause less problemsuse_force_update
->state_forceupdater
would outline being part of thestate_
bunch, and would avoid any misunderstanding about the forced update happening where the "magic state" is defineduse_memo
(Get a immutable reference to a memoized value, computed through a callback) ->state_memoized
? What difference withuse_callback
(Get a immutable reference to a memoized Callback) ?use_mut_ref
I'm unsure: it nearly fits the criteria to be called a state variable too, except it is ignored. That just looks like some sort of "global variable"... so... justglobal_variable
? (it would be useless if it could not be mutated, anyway, right?)- as for
use_effect
, the API doc does tell that this is a hook "called every time after the component’s render has finished", that much seems clear, except that we give it a closure returning another ("cleanup", if I trust the comment in the example; "destructor" I deduce from the next paragraph, which would surely help more before the example) closure, so one of them likely is the one called "after the component’s render has finished", but what does it really mean that the second one "is called when the component is re-rendered"? Does this refer to effective DOM updating, as opposed to VDOM updating? Even if yes, what do I know about when exactly VDOM changes are propagated to DOM (as soon as detected? batch when all was diff'd? other?)
Also, I don't see what "is used for hooking into the component’s lifecycle" would refer to aside from this, so I'd tend to just drop it. Maybepost_render_hook
would be a more descriptive name?
Another aspect that would also need more details is the use of "dependencies": many examples show ()
as dependency to prevent any change of the impacted state, and the fact is uses a generic type makes it far from obvious what else can be used. Would it be that it could just be any value, which would stored as state and compared to potentially trigger the nominal behavior?
In the case of use_effect
, which IIUC does not provide any state otherwise, it seems that use_effect_with
would be the thing that blurs the line between what is a state variable and what is a hook. Are there other such examples, that would not fall into only one of those categories?
Oh, and only when reading the example of use_node_ref
do I get an idea that the dependency value gets passed to the callback we give to use_effect_with
, this kind of things ought to be documented explicitly.