justin-schroeder / arrow-js

Reactivity without the framework
https://arrow-js.com
MIT License
2.32k stars 50 forks source link

Nested template being called unexpectedly #89

Open madelson opened 9 months ago

madelson commented 9 months ago

I have a conditionally-included template like this:

const state = reactive({ items: [], index: 0 });

...
${() => hasItem()
            ? html`
                ${() => currentItem().loaded !== false
                    ? html`
                        <img src="${() => currentItem().url}" 
                             @load="${e => onImageLoaded(e, true)}" 
                             @error="${e => onImageLoaded(e, false)}">
                        ${() => currentItem().loaded === null ? loadingAnimation : null}`
                    : html`<div style="color: red;">Item failed to load</div>`}
                <div>Current rating: ${() => currentItem().rating}</div>
            </div>`
            : loadingAnimation}
...

function hasItem() { return state.items.length > state.index; }
function currentItem() { return hasItem() ? state.items[state.index] : null; }

state is a reactive object with an array items and an integer property index. What surprises me is that sometimes I am hitting a javascript error on this line:

<div>Current rating: ${() => currentItem().rating}</div>

The problem is that currentItem() is null. However, I would have expected this not to be called because of the hasItem() conditional. Am I misunderstanding something about how Arrow is supposed to work with conditional templates?

justin-schroeder commented 9 months ago

I think the issue here (could be wrong) is arrow doesn’t destroy the previous template but memoizes it for future re-insertion (like <KeepAlive>) which means effects are still running on it even when it isnt mounted. Probably something we should fix in future iterations.

madelson commented 9 months ago

Makes sense. I do think it would be desirable if the control flow could be respected. For the time being, is there any workaround to force arrow to ditch the template?