Svelte: onMount triggers in reverse order for siblings

Created on 20 Mar 2019  ยท  12Comments  ยท  Source: sveltejs/svelte

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

bug

All 12 comments

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.

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

https://github.com/sveltejs/svelte/blob/60e73c41dceaad8354c312105edfadc887849f7b/src/internal/scheduler.js#L55

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?

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

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.

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?

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.

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 ๐Ÿ˜‚

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.

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).

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.

@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.

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mmjmanders picture mmjmanders  ยท  3Comments

ricardobeat picture ricardobeat  ยท  3Comments

noypiscripter picture noypiscripter  ยท  3Comments

plumpNation picture plumpNation  ยท  3Comments

rob-balfre picture rob-balfre  ยท  3Comments