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

onMount triggers in reverse order for siblings #2281

Closed
unindented opened this issue Mar 20, 2019 · 12 comments
Closed

onMount triggers in reverse order for siblings #2281

unindented opened this issue Mar 20, 2019 · 12 comments
Labels

Comments

@unindented
Copy link

When rendering a list of components (1, 2, 3) they trigger their respective onMounts in the opposite order (3, 2, 1). I think this is unintuitive.

React would trigger these events in order (1, 2, 3), but I don't know if that affects your decision process.

Anyways, here's a repro: https://v3.svelte.technology/repl?version=3.0.0-beta.20&gist=5f85713af12be6cfc5da9f2b812c57cd

@Rich-Harris
Copy link
Member

Related: parent onMount happens before child onMount. I don't think that's intentional. We probably just need to do a pop instead of a shift somewhere or vice versa.

@Rich-Harris Rich-Harris added this to the 3.x milestone Apr 25, 2019
@EmilTholin
Copy link
Member

Just like you suspected the onMount functions are called FirstChild -> SecondChild -> ... -> Parent by changing this pop to a shift:

const callback = render_callbacks.pop();

Question is if that messes up the order of all the other types of render callbacks? Maybe a new onmount_callbacks array should be introduced in the scheduler?

@direct-fuel-injection
Copy link

hello blat',
wtf is going on here with onMount order
https://svelte.dev/repl/9eb25e5039844a9588cd96bc7380e672?version=3.6.4

@jpinho
Copy link

jpinho commented Nov 23, 2020

The behavior described above by @direct-fuel-injection is still happening. Is this something that is supposed to be fixed? I just bumped into this on a client codebase and it's a pain.

@benwoodward
Copy link

benwoodward commented Nov 27, 2020

Are the onMount callbacks meant to be fired parents first, or children first?

The problem I've just run into (on 3.29.0) is that I need to add a simple shim for process.cwd for all my components, otherwise the app falls over:

  // App.svelte
  onMount(() => {
    // VFile fix
    window.process.cwd = () => {};
  });
core.js:55 Uncaught TypeError: process.cwd is not a function
    at new VFile (core.js:55)
    at VFile (core.js:49)
    at Function.parse (index.js:273)
    at instance$t (index.svelte:6)
    at init (index.mjs:1447)
    at new Reviews (index.svelte:6)
    at create_fragment$u (App.svelte:140)
    at init (index.mjs:1462)
    at new App (App.svelte:131)
    at app.js:6

If the children are mounted first, then it's not possible for me to create this app-wide shim, and so I have to add it to every component that imports the problematic library that this shim is for... which leads to a lot of code-duplication. Maybe not such a big deal, but it does seem unintuitive to me.

Perhaps there's a better way for me to solve my problem that I'm not aware of?

@PatrickG
Copy link
Member

Are the onMount callbacks meant to be fired parents first, or children first?

Yes.

Perhaps there's a better way for me to solve my problem that I'm not aware of?

Set the prop on window earlier.
Maybe in main.js or in App.svelte outside onMount.

@jpinho
Copy link

jpinho commented Nov 27, 2020

Are the onMount callbacks meant to be fired parents first, or children first?

Yes.

Perhaps there's a better way for me to solve my problem that I'm not aware of?

Set the prop on window earlier.

Maybe in main.js or in App.svelte outside onMount.

I love the Yes (true) answer to an OR question 😂

@pngwn
Copy link
Member

pngwn commented Nov 27, 2020

Parent mount starts first first and finishes last, nothing else makes any sense.

Child onMount will always be called first because it is called when the component has mounted, a parent cannot complete its mount until its children have been successfully mounted.

@jpinho
Copy link

jpinho commented Nov 27, 2020

Then we need an afterMount 🎉 .
Also, that behavior differs from React, so may lead into confusion, maybe rename onMount to onMountInit.

Also, a diagram of the lifecycle and their meaning in the Svelte world would be cool (I can help if needed).

@benwoodward
Copy link

Thanks for the explanation Penguin, that makes a lot of sense. Stay warm.

Also, that behavior differs from React, so may lead into confusion, maybe rename onMount to onMountInit.

..or onMountedItInnit..? I think the current onMount should definitely be renamed to onMayyyyybeMounted 😬

This probably sounds like pedantry, but even though an implementation that aligns with React might be the right solution, I disagree that things should default to the way that React does things just because React has the biggest mindshare, that's how we end up with 200 JS frameworks that do the same thing in slightly different ways. I never used React because it just seemed like an over-engineered mess. So from my perspective, it makes more sense to start from the assumption that the way React does things is more likely to be something not to copy.

Anyway, would love to see a diagram also.

@jpinho
Copy link

jpinho commented Nov 28, 2020

@benwoodward I was hesitating to throw the React comparison. I understand Svelte presents a different paradigm. But many Svelte adopters will have had previous contact with React (being it good or bad, doesn't matter) and so this means naming is really important (pedantic here matters).

Also, when I suggested the onMountInit I was thinking on a mature web framework... ASP.NET. Their web pages facing code behind were also compiled, and I think Svelte can pull some inspirations from it. Specially from the Page Lifecycle (for reference https://www.c-sharpcorner.com/UploadFile/8911c4/page-life-cycle-with-examples-in-Asp-Net)

I've done some hacks to achieve what you intent. Maybe can give you a hand.

@PatrickG
Copy link
Member

Are the onMount callbacks meant to be fired parents first, or children first?

Yes.

Perhaps there's a better way for me to solve my problem that I'm not aware of?

Set the prop on window earlier.
Maybe in main.js or in App.svelte outside onMount.

I love the Yes (true) answer to an OR question 😂

Haha, seems I only read half the question :D

Then we need an afterMount 🎉 .
Also, that behavior differs from React, so may lead into confusion, maybe rename onMount to onMountInit.

Also, a diagram of the lifecycle and their meaning in the Svelte world would be cool (I can help if needed).

The onMount already fires after everything is mounted (thats your afterMount).
Good to see in the @direct-fuel-injection's repl

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants