Svelte: Bug: the first template render happens before `onstate`

Created on 5 Jun 2018  路  6Comments  路  Source: sveltejs/svelte

onstate should be called before every render, but it is not called before the initial render. It is called before every subsequent render though, so that's good, but it needs to run before the first (I think). If it doesn't there is no way to change the data before that initial render since oncreate also happens after the initial render and after onstate.

See https://svelte.technology/repl?version=2.7.0&gist=15eb8d37be3fefa75497b94fd19fec44

bug

Most helpful comment

@kaisermann we already solved this in chat, but I'm documenting the solution here for posterity.

If you experience any breaking changes, it is likely because you are modifying/accessing the DOM inside onstate using this.refs.myDomNode. This may have been buggy behavior in your app since onstate was inconsistent before this update, being called _after_ the DOM is updated the first time, but _before_ it is updated every other time. This means the first time the DOM is in the correct state, and after it is stale (e.g. an element inside an if-block might not exist when it should).

The fix is to put anything that relies on the DOM (any references to this.refs.*) inside onupdate where it should have been all along.

All 6 comments

fixed in 2.11. Hopefully wasn't a breaking change...

@Rich-Harris spoilers: it was 馃槶

@kaisermann we already solved this in chat, but I'm documenting the solution here for posterity.

If you experience any breaking changes, it is likely because you are modifying/accessing the DOM inside onstate using this.refs.myDomNode. This may have been buggy behavior in your app since onstate was inconsistent before this update, being called _after_ the DOM is updated the first time, but _before_ it is updated every other time. This means the first time the DOM is in the correct state, and after it is stale (e.g. an element inside an if-block might not exist when it should).

The fix is to put anything that relies on the DOM (any references to this.refs.*) inside onupdate where it should have been all along.

@jacwright I guess we should put this somewhere in the onstate section of the docs.

// this fires before oncreate, and on every state change.
// the first time it runs, `previous` is undefined

It's not clear enough for this case 馃

Good point. Do it! Doooo eeeet. Or I will if I remember.

I added a rule to @tivac/eslint-plugin-svelte to try and catch this.

onstate-this-refs

It's in v1.2.0

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Rich-Harris picture Rich-Harris  路  3Comments

rob-balfre picture rob-balfre  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments

1u0n picture 1u0n  路  3Comments

ricardobeat picture ricardobeat  路  3Comments