Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Reactive data may trigger recursive updates when created in template render. #12924

Open
rlsz opened this issue Feb 21, 2025 · 2 comments
Open

Comments

@rlsz
Copy link

rlsz commented Feb 21, 2025

Vue version

3.5.13

Link to minimal reproduction

https://play.vuejs.org/#eNp9UktLJDEQ/iu1uWQGZnuQ3ZM7CvsQdvegooKXXGJ3dRtNJyGPdqDp/24lYVREvITU90jqq2RmP51rpoTsmO1C65WLEDAmdyqMGp31EWbw2G9okW1UE8ICvbcjcDJxYYRprQkRxjDASVau+F/U2sKt9br7wtfC9MmQ0xoYMN5giH9klEerNczCAFR3R1Cx1ztW87L+cWCtxkbbYcVTQFAGrEMvo/V8A1zLO9Q8o/mE6sm7phB0Iqcw9XTZR/Sk5EXkKaOvLqoXYXbbmp5yUxFxdFpGpApgd390Os8l4bLstlQVVBmXIkxfR9uhPhGMeMFgW8lOTdnzLnG2ZyZf9+YKtmExUNReDc1DsIbeosxGsNaOTmn0Fy4PMAh2XKeWOUlTfvpfsOgTbg54e4/t4wf4Q9hnTLBLjwH9hIK9cFF6arXSZ9fnuKf9C0kBkyb1J+QV0jOl3GOV/Uqmo7bf6Eq3/8qPUma4CWf7iCYcQuVGs3IpesHob/3+JPpru9+a78VHb8iWZ1n+7ug=

Steps to reproduce

Run, then catch error in console.

What is expected?

no recursive updates

What is actually happening?

recursive updates

System Info

Any additional comments?

bug conditions:

  1. create reactive data when template render
  2. access some prop with 'in' operator
  3. set value of that prop after the access
@edison1105 edison1105 added 🐞 bug Something isn't working 🔩 p2-edge-case and removed 🐞 bug Something isn't working labels Feb 21, 2025
@OnlyWick
Copy link
Contributor

OnlyWick commented Feb 25, 2025

The core of this problem is that every time the function is re-executed, a new object is created, which cannot hit the proxyMap cache. Subsequently, when triggers perform dep.track , they also fail to hit the depsMap cache, resulting in a large number of dep links being generated. To address this issue, we need to avoid creating new objects each time. Unfortunately, this cannot be achieved with the current implementation architecture.

<script setup>
import { ref, reactive } from 'vue'

const msg = ref('Hello World!')
const obj = {}  // Avoid recreating objects
// or
// const data = reactive({});
function getTestData1() {
  const data = reactive(obj);
  console.log('use in operator', 'label' in data);
  data.label = 'set data after in';
  return data;
}
</script>

@rlsz
Copy link
Author

rlsz commented Feb 27, 2025

The core of this problem is that every time the function is re-executed, a new object is created, which cannot hit the proxyMap cache. Subsequently, when triggers perform dep.track , they also fail to hit the depsMap cache, resulting in a large number of dep links being generated. To address this issue, we need to avoid creating new objects each time. Unfortunately, this cannot be achieved with the current implementation architecture.

<script setup> import { ref, reactive } from 'vue' const msg = ref('Hello World!') const obj = {} // Avoid recreating objects // or // const data = reactive({}); function getTestData1() { const data = reactive(obj); console.log('use in operator', 'label' in data); data.label = 'set data after in'; return data; } </script>

Yes, I solve this with same workaround. The original code doesn't bite without the 'in' operator, but production code will be generated to 'in' operator, which cause my problem.

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants