Skip to content

v-for not re-rendering multiple computed values when associated data is changed. #240

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

Closed
kharysharpe opened this issue Jun 1, 2018 · 4 comments

Comments

@kharysharpe
Copy link

Version

1.3.1

Reproduction link

https://play.nativescript.org/?template=play-vue&id=H8Tsz0&v=11https://play.nativescript.org/?template=play-vue&id=H8Tsz0&v=11https://play.nativescript.org/?template=play-vue&id=H8Tsz0&v=11https://play.nativescript.org/?template=play-vue&id=H8Tsz0&v=11

Platform and OS info

iOS 11.3.1 / NativeScript 3 ( & 4) / MacOS 10.13.4

Steps to reproduce

  1. Search for "foo"
  2. then search for "bar"

What is expected?

The list to show all titles in the 3 lists that contain bar

What is actually happening?

Fails on second search.

Partial Logs:

[iPhoneTestDevice]: 'You are searching for [Foo]'
[iPhoneTestDevice]: '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> ParentNode(ElementNode(stacklayout))'
[iPhoneTestDevice]: '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> RemoveChild(ElementNode(stacklayout), ElementNode(stacklayout))'
[iPhoneTestDevice]: '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> ParentNode(ElementNode(stacklayout))'
[iPhoneTestDevice]: '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> ParentNode(ElementNode(stacklayout))'
[iPhoneTestDevice]: '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> RemoveChild(ElementNode(stacklayout), ElementNode(stacklayout))'
[iPhoneTestDevice]: '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> RemoveChild(ElementNode(stacklayout), ElementNode(stacklayout))'
[iPhoneTestDevice]: 'You are searching for [Bar]'
[iPhoneTestDevice]: ERROR: [Vue warn]: Error in nextTick: "Error: Can't insert child, because it is already a child."


Attempting to display 3 lists that are filtered based on a single keyword.

@rigor789
Copy link
Member

rigor789 commented Jun 6, 2018

We have figured out a temporary solution on slack - wrap every v-for in a parent layout. Seems like multiple v-fors in the same block are not working, which is most likely related to #127 where v-if's in the same block produce the same issue.

@starryalley
Copy link

starryalley commented Jun 15, 2018

We got exactly the same issue, but there is just one v-for.

Our app has a search page, where the first search without any filter gives roughly 138 results (all items) where results are rendered by:

<StackLayout>
    <StackLayout v-for="item in searchResults" :key="item.id" >
        <GridLayout class="result-row" rows="*" columns="*,*,*,*,*">
             <Label row="0" col="0" ..../>
             <Label row="0" col="1" ..../>
             <Label row="0" col="2" ..../>
             <Label row="0" col="3" ..../>
             <Label row="0" col="4" ..../>
        </GridLayout>
    </StackLayout>
</StackLayout>

A second search will hang the UI with exactly the same error.

The weird thing is when we do first search with some filter applied, and results count are roughly 50 rows, the next search won't hang and it works correctly as long as we don't do a search when no filter is applied.

There is only one v-for in <template> and it's already wrapped in a StackLayout.

Since repeated search (with some filter applied) always works correctly, and it only hangs when we do a search after a search without filter, which means listing all items. I start to suspect the :key. I then make :key="item.id + Math.random()" and it solves our issue. This just make sure the key is always different across searches.

However it introduces another minor issue. I run the app by npm run watch:ios with Vue.config.silent = false;. When doing a search without filter, webpack always crashes:

CONSOLE LOG '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> CreateElement(Label)'
CONSOLE LOG '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> SetAttribute(ElementNode(label), data-v-7cb41050, )'
CONSOLE LOG '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> AppendChild(ElementNode(gridlayout), ElementNode(label))'
CONSOLE LOG '{NSVue (Vue: 2.5.13 | NSVue: 1.3.1)} -> CreateElement(Label)'
error: uncaughtException: 120 date=Fri Jun 15 2018 23:05:16 GMT+1000 (AEST), pid=47089, uid=501, gid=20, cwd=XXXXX, execPath=/usr/local/Cellar/node@8/8.11.2/bin/node, version=v8.11.2, argv=[/usr/local/Cellar/node@8/8.11.2/bin/node, ,XXXXX/node_modules/.bin/webpack, --watch, --env.tnsAction, run, --env.ios], rss=180903936, heapTotal=178057216, heapUsed=161481920, external=1783057, loadavg=[2.919921875, 2.9150390625, 2.884765625], uptime=226688, trace=[], stack=undefined

App continues to work correctly though.

Guess this might be related?

Edit: When commenting out Vue.config.silent = false line, npm run watch:ios won't crash anymore.. Is a 138-row result set where each one creates 5 Labels and 2 Layouts considered too much?

@rigor789
Copy link
Member

rigor789 commented Jun 15, 2018

@starryalley interesting that setting the key to a random value solves this...

Is a 138-row result set where each one creates 5 Labels and 2 Layouts considered too much?

Yes, I would say that's too much, consider using a ListView, which in return would only create (depending on the visible area) about 10 rows with 5 labels, and as you scroll update them (view recycling).

That's 690 views vs ~50, quite a difference!

@nativescript-vue-bot
Copy link
Collaborator

We are locking this issue because it has been closed for more than 14 days.

If the issue comes up again please open a new issue with additional details.

@nativescript-vue nativescript-vue locked as resolved and limited conversation to collaborators Jul 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

4 participants