Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/render-function-vnodes-must-be-unique.md
1---2title: VNodes Must Be Unique in Render Functions3impact: HIGH4impactDescription: Reusing vnode references causes rendering bugs and unexpected behavior5type: gotcha6tags: [vue3, render-function, vnode, composition-api]7---89# VNodes Must Be Unique in Render Functions1011**Impact: HIGH** - Reusing the same vnode reference multiple times in a render function tree causes rendering bugs, where only one instance appears or updates behave unexpectedly.1213Every vnode in a component's render tree must be unique. You cannot use the same vnode object multiple times. If you need to render the same element multiple times, create each vnode separately using a factory function or by calling `h()` in a loop.1415## Task Checklist1617- [ ] Never store a vnode in a variable and use it multiple times in the same tree18- [ ] Use a factory function or `.map()` to create multiple similar vnodes19- [ ] Each `h()` call creates a new vnode, so call it for each instance needed20- [ ] Be especially careful when extracting vnode creation into helper functions2122**Incorrect:**23```javascript24import { h } from 'vue'2526export default {27setup() {28return () => {29// WRONG: Same vnode reference used twice30const p = h('p', 'Hello')31return h('div', [p, p]) // Bug! Duplicate vnode reference32}33}34}35```3637```javascript38import { h } from 'vue'3940export default {41setup() {42return () => {43// WRONG: Reusing vnode in different parts of tree44const icon = h('span', { class: 'icon' }, '★')45return h('div', [46h('button', [icon, ' Save']), // Uses icon47h('button', [icon, ' Delete']) // Reuses same icon - Bug!48])49}50}51}52```5354**Correct:**55```javascript56import { h } from 'vue'5758export default {59setup() {60return () => {61// CORRECT: Create new vnode for each use62return h('div', [63h('p', 'Hello'),64h('p', 'Hello')65])66}67}68}69```7071```javascript72import { h } from 'vue'7374export default {75setup() {76return () => {77// CORRECT: Factory function creates new vnode each time78const createIcon = () => h('span', { class: 'icon' }, '★')79return h('div', [80h('button', [createIcon(), ' Save']),81h('button', [createIcon(), ' Delete'])82])83}84}85}86```8788```javascript89import { h } from 'vue'9091export default {92setup() {93return () => {94// CORRECT: Using map to create multiple vnodes95return h('div',96Array.from({ length: 20 }).map(() => h('p', 'Hello'))97)98}99}100}101```102103```javascript104import { h } from 'vue'105106export default {107setup() {108const items = ['Apple', 'Banana', 'Cherry']109110return () => h('ul',111// CORRECT: Each iteration creates a new vnode112items.map((item, index) =>113h('li', { key: index }, item)114)115)116}117}118```119120## Why VNodes Must Be Unique121122VNodes are lightweight JavaScript objects that Vue's virtual DOM algorithm uses for diffing and patching. When the same vnode reference appears multiple times:123- Vue cannot differentiate between the instances124- The diffing algorithm produces incorrect results125- Only one instance may render, or updates may corrupt the DOM126127Each vnode maintains its own identity and position in the tree, which is essential for:128- Correct DOM patching during updates129- Proper lifecycle hook execution130- Accurate key-based reconciliation in lists131132## Reference133- [Vue.js Render Functions - Vnodes Must Be Unique](https://vuejs.org/guide/extras/render-function.html#vnodes-must-be-unique)134