Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: inconsistent behavior in rendering and lifecycle hooks #200

Open
wayeast opened this issue Aug 16, 2019 · 9 comments

Comments

@wayeast
Copy link

commented Aug 16, 2019

I do not know if this is an issue with seed or with my usage of it, but there are two patterns of behavior that are puzzling me. One is with rendering, which may or may not be triggered after a model update; another is with lifecycle hooks, which seem to require different conditions to fire.

I have created a small toy example here that reproduces the issues I'm running into in my project. This code can be dropped into the seed quickstart repo and run as is. I've added comment blocks to point out where the problems occur and my puzzlement over them, but they are essentially this:

  1. DOM rendering does not appear to be triggered after some updates. In my example, I don't understand why the update highlighted is not rendered while updates that follow the same pattern a few lines above are.
  2. A lifecycle hook in a simple div here is fired just fine, while another requires an extra div wrapper to fire. If I repeat the same pattern from a few lines above, the latter closure will not fire!

Any help to understand what's going on and how to work with these patterns would be appreciated.

@MartinKavik

This comment has been minimized.

Copy link
Contributor

commented Aug 16, 2019

The root of all evil is did_mount. We are discussing hooks here: #82. They don't work reliably (and probably somehow break render loop in your example) and in the most cases it's an anti-pattern to use them.

I've refactored your example: https://gist.github.com/MartinKavik/c8ef497a26c6506d2b1f5615397f5b45 (see comment).

Thanks for a good question and the example.

P.S. If you want some inspiration for auth and login form, you can look at https://github.com/MartinKavik/seed-rs-realworld.

@rebo

This comment has been minimized.

Copy link

commented Aug 16, 2019

Also having some issues with did_mount, sometimes they fire and sometimes not.

However I need something to fire so I can trigger re-rendering of MathJax.

@MartinKavik

This comment has been minimized.

Copy link
Contributor

commented Aug 16, 2019

@rebo Could you send link to the minimal example with your use-case of did_mount to #82? So we can fix and design better hooks (or remove them).

@rebo

This comment has been minimized.

Copy link

commented Aug 16, 2019

Hi Yes sure, i also have another issue i need to make a minimal example of. Will endeavour to get both done this evening.

@rebo

This comment has been minimized.

Copy link

commented Aug 17, 2019

This gist seems to exhibit the issue:

https://gist.github.com/rebo/d9a1c6314ce1726e77b74708afd87d4d

Sorry it is fairly long however i had to incorporate much of the Node structure in my original app in order to trigger the problem. The app requires tailwindcss as well as fontawesome to properly render.

I think it is something to do with the structure of the Nodes generate in the ::detail_pane function:

pub fn detail_pane(entity: &Thing, model: &Model) -> Node<Msg> {
    if model.edit_detail_pane.is_some() {
        modal_confirm_cancel_dialog(
            entity.name.clone(),
            div![form(&entity, FormType::Update)],
            "Update".to_string(),
            Msg::Update,
            "Cancel".to_string(),
            Msg::Cancel,
        )
    } else {
       modal_confirm_cancel_dialog(
            entity.name.clone(),
            div![detail(&entity)],
            "Edit".to_string(),
            Msg::Edit,
            "Close".to_string(),
            Msg::Cancel,
        )
    }
}

The first time a user triggers this function it goes down the None path and shows a modal detail pane. The node structure for this is generated by ::modal_confirm_cancel_dialog which takes ::detail(&entity) as an argument.

When the user clicks edit, the ::detail_pane takes the Some path and renders a form.

I think when rendering the Some path (rendering ::form) it clashes with the hooks in ::detail. and the hook inside ::form is never triggered.

Strangely enough if I change the div![detail(&entity)] in the above function to p![detail(&entity)] then the bug goes away and the hook is triggered correctly.

I need most of the above hooks as they re-render mathjax on view update.

EDIT In the mean time I am having more success using Orders and perform_cmd than the lifetime hooks

@MartinKavik

This comment has been minimized.

Copy link
Contributor

commented Aug 17, 2019

@rebo
I suggest to delete all hooks and replace them with custom elements - I've refactored Seed's mathjax example to use custom element (#202) for inspiration.
After that your Rust code with business logic should be shorter & easier to reason about (especially fn detail).
Do you think there is a case in your code where you have to use hooks and there is no other option?


In the mean time I am having more success using Orders and perform_cmd than the lifetime hooks

Nice!


Note: You are using Tailwind => look at https://github.com/MartinKavik/seed-quickstart-webpack.

@rebo

This comment has been minimized.

Copy link

commented Aug 17, 2019

Thanks for the advice regarding the custom elements I will look at that now.

And yep I'm using your seed-quickstart-webpack with yarn etc. Its great!

Edit:: I like the custom element example it is very neat. That said because my mathematics is embedded in markdown it is a bit difficult to extract the mathematics itself. The Orders perform command is working very well though and I will stick with this.

One area that I am using did_mount is for input focusing. If these hooks were removed how would this use case be handled? (maybe by an Order command again?)

@wayeast

This comment has been minimized.

Copy link
Author

commented Aug 17, 2019

@MartinKavik thanks for the refactored code. I have been able to go back through my project and make changes in accordance with you suggestions. The problems I mentioned on opening this thread (appear to) have been solved.

@MartinKavik

This comment has been minimized.

Copy link
Contributor

commented Aug 17, 2019

@rebo

One area that I am using did_mount is for input focusing. If these hooks were removed how would this use case be handled? (maybe by an Order command again?)

  1. You can use attribute autofocus - see a month old change in Seed core.
    Example:
input![
    attrs! { At::AutoFocus => AtValue::None }
]
  1. Or set it manually (as you probably suggested with Orders) when do you want with the code like the one in the core.

If none of these options are applicable for you, just create a small example and we will find another solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.