fix(vue-table): prevent unnecessary DOM mutations in FlexRender for function renderer#6200
fix(vue-table): prevent unnecessary DOM mutations in FlexRender for function renderer#6200Mini-ghost wants to merge 1 commit intoTanStack:mainfrom
FlexRender for function renderer#6200Conversation
… function renderers
|
|
Important Review skippedToo many files! This PR contains 295 files, which is 145 over the limit of 150. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (5)
📒 Files selected for processing (295)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
FlexRender for function renderer
🎯 Changes
This PR fixes an issue in Vue
FlexRenderwhere function renderers can cause unnecessary DOM mutations.Problem
When
columnsare created withcomputed(() => [...]), every dependency change recreates the whole column definitions, including newcellfunction references.At the same time,
FlexRenderhandles function renderers withh(props.render, props.props). Whenprops.renderis a function, Vue treats it as a component type. Because the function reference changes after each re-evaluation, Vue sees it as a different component and triggers an unnecessary unmount/remount. As a result, the DOM can still be mutated even when the cell content has not changed.This can be observed in the Chrome DevTools Elements panel: after typing in the search input, the
<td>for Alice's Phone cell is still marked as updated even though its content remains the same.Mini reproduction: https://stackblitz.com/edit/vitejs-vite-xxp2iyaa?file=src%2FApp.vue&terminal=dev
Cause
columnsis created withcomputed(() => [...]), so each re-evaluation creates new column and renderer referencesFlexRenderpasses function renderers toh(), so Vue treats them as component typesSolution
This change handles function renderers and component renderers differently:
props.renderis a function, it callsprops.render(props.props)directlyprops.renderis an object, it usesh(props.render, props.props)This avoids treating a plain function renderer as a component type, which helps prevent unnecessary DOM mutations.
Additional note
This issue can also be easier to trigger depending on how the user defines
columns.If
columnsis placed insidecomputed(() => [...]), every dependency change recreates all column definitions, including newheader/cellfunction references:If it is changed to a stable constant array, and the dynamic part is moved into
header: () => ..., it can avoid recreating renderer references on every re-evaluation. This can be used as a temporary workaround on the user side:However, this is only a user-side workaround. It does not fix the root cause, which is that
FlexRendertreats a function renderer as a component type.✅ Checklist
pnpm test:pr.