dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

Documentation "bug"/proposal: emphasize hook fundamentals more when introducing them

Open werner291 opened this issue 1 year ago • 2 comments

Hi!

so, I kinda noticed myself getting into all sorts of headaches to try to get the existing hooks to do what I wanted... I then reviewed the custom hooks documentation (https://dioxuslabs.com/learn/0.4/cookbook/state/custom_hooks)) and it kinda just... clicked, how hooks work?

In the current reading order, hooks seem kinda magic, and "custom hooks" sound like scary advanced functionality that is probably not relevant unless I wanna do complicated stuff.

Once I read that chapter... No. They're not magic. They run the closure you give them once, store the result, and return a reference to that every invocation of the state function. That's all.

I believe that the documentation would be improved if you started with introducing cx.use_hook (rather than higing it in the cookbook), and introduced the standard hooks after.

To make an analogy with Haskell... do-notation and monads also seemed like magic for a while. In hindsight, I consider do-notation (especially with the IO monad) harmful to new learners because it obscures the underlying functionality that in reality was very simple... Learning to manually bind monads together with >= (or whatever the operator was) was far more educational. (Do-notation was afterwards also far more useful because I actually understood it.)

Just a proposal :3

werner291 avatar Jan 01 '24 00:01 werner291

so, I kinda noticed myself getting into all sorts of headaches to try to get the existing hooks to do what I wanted... I then reviewed the custom hooks documentation (https://dioxuslabs.com/learn/0.4/cookbook/state/custom_hooks) and it kinda just... clicked, how hooks work?

Thanks for the feedback! It is always useful to hear what parts of the guide are confusing. Did you read the guide, reference?

I think explaining cx.use_hook is less important than explaining the API of individual hooks, but the custom hooks chapter might do a better job of explaining state hooks (use_ref, use_state, use_shared_state, cx.use_hook) than the guide or reference. It might make sense to change the wording in the guide and reference to be more similar to the explanation of hooks in the custom hook guide

I am hesitant to introduce cx.use_hook too early because it is very easy to loose reactivity (or not trigger UI to update when state changes) if you use cx.use_hook. For example, if you know about cx.use_hook, but not use_state then this version of the code from the homepage example compiles, but mysteriously doesn't work:

fn app(cx: Scope) -> Element {
    let mut count = cx.use_hook(|| 0);

    render!(
        h1 { "High-Five counter: {count}" }
        button { onclick: move |_| *count += 1, "Up high!" }
    )
}

They run the closure you give them once, store the result, and return a reference to that every invocation of the state function. That's all.

That is true for some hooks like use_ref and use_state. Other hooks like use_effect, and use_future may rerun the closure many time. Or hooks like use_callback will return a different value every time you call the hook. Internally, many of them use cx.hook, but they don't always follow that API

ealmloff avatar Jan 01 '24 00:01 ealmloff

Well, the order in which I read guides and documentation can be quite chaotic, so perhaps that's at least partly on me... But I'm sure I'm not the only one (and given the sheer amount of documentation out there about various bits of software we use... perhaps it's a common time-saving tactic?). Perhaps a bit of redundancy or cross-linking couldn't hurt.

Basically, I'd been using use_state, use_ref and use_signal with some amount of success, but the difference between them was not quite clear to me and a co-contributor to the IM client we're trying to write. Like... Yeah, we get they're different, but not quite when to use which. (We're trying to standardize on signals where we can at the moment though.)

Also, I found myself trying to force-fit a somewhat complex logical structure (basically, I wanted to tie an UnboundedSender together with a struct holding a few state variables that would not really make sense together; use_coroutine doesn't fit there because it only exposes the sender and not associated data) into the standard hooks while a custom hook would have worked better.

They run the closure you give them once, store the result, and return a reference to that every invocation of the state function. That's all.

This was referring to cx.use_hook specifically, actually; that's what it does internally.

Perhaps you could show the implementation of use_state when you introduce them? Just something brief, like "Hey, this stores a ref, it clones stuff, and it notifies stuff. See? Here's the notifier in the definition."

werner291 avatar Jan 01 '24 11:01 werner291