Skip to content
This repository was archived by the owner on Sep 24, 2021. It is now read-only.
This repository was archived by the owner on Sep 24, 2021. It is now read-only.

Reassignment after rendering conditional element / array item rendered twice #9

@kaleidawave

Description

@kaleidawave

Given the following template:

<template>
    <div #if="someString !== 'x'">
        {someString}
    </div>
</template>

Let someString equal 'x' initially.

If someString is reassigned to "abc" then at runtime:

  1. someString !== 'x' is now truthy so the div is rendered with the state (this.data equal to) {someString: "abc"} and swapped in for a placeholder element
  2. someString value has changed so it tries to set the first text node of the div (if it exists) content to "abc"

The problem is when the render of the div occurs it will render in with the updated state so it will have "abc" as its text content. Therefore the second call is redundant for this update. However a second assign to someString of "xyz" requires the second statement, as the update would not be reflected on the view as the render of the div and swap would not occur.

This isn't a big deal here, no bad effects only additional calls with no effect which could be a perf problem.

However for:

<template>
    <div #if="someArr.length > 3">
        <ul #for="const x of someArr">
             <li>{x}</li>
        </ul>
    </div>
</template>

.pushing to someArr while someArr.length === 3 will cause the argument of push to be in the ul list twice. Once from initial render when someArr.length > 3 becomes truthy and second when the push call means assigning to a index outside of current length causing a new li to be rendered.

There are some mitigations such as maintaining a separate prop for the condition as not to clash with variables used inside and controlling that prop manually.

But there is definitely some ways the compiler could see this problem occurring and generate code for mitigations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingclient-side-reactivityReflection of updates to state on the view

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions