Skip to content

Commit 3aefe2c

Browse files
committed
Reactive Updates for Nested Components in Functional VDOM #7046
1 parent df0eba1 commit 3aefe2c

1 file changed

Lines changed: 40 additions & 7 deletions

File tree

src/functional/component/Base.mjs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ class FunctionalBase extends Base {
279279
return vdomTree
280280
}
281281

282+
const me = this;
283+
282284
// Check if it's a component definition (functional or classic)
283285
if (vdomTree.className || vdomTree.module || vdomTree.ntype) {
284286
// Components are reconciled based on their `id` property in the VDOM definition.
@@ -295,36 +297,67 @@ class FunctionalBase extends Base {
295297
}
296298

297299
// If the component already exists (e.g., from a previous render cycle), reuse it
298-
let newComponent = this.childComponents?.get(componentKey);
300+
let component = me.childComponents?.get(componentKey);
299301

300-
if (!newComponent) {
301-
this.childComponents ??= new Map();
302+
if (!component) {
303+
me.childComponents ??= new Map();
302304

303305

304306
// Instantiate the component
305-
newComponent = Neo[(vdomTree.className || vdomTree.module) ? 'create' : 'ntype']({
307+
component = Neo[(vdomTree.className || vdomTree.module) ? 'create' : 'ntype']({
306308
...vdomTree,
307309
parentId,
308310
parentIndex
309311
})
312+
} else {
313+
const newConfig = {...vdomTree}; // Shallow copy
314+
315+
delete newConfig.className;
316+
delete newConfig.id;
317+
delete newConfig.module;
318+
delete newConfig.ntype;
319+
320+
component.set(newConfig)
310321
}
311322

312323
// Add to the new map for tracking in this render cycle
313-
this.#newChildComponents.set(componentKey, newComponent);
324+
me.#newChildComponents.set(componentKey, component);
314325

315326
// Replace the definition with a reference using the component's own method
316-
return newComponent.createVdomReference();
327+
return component.createVdomReference();
317328
}
318329

319330
// Recursively process children
320331
if (vdomTree.cn && Array.isArray(vdomTree.cn)) {
321332
vdomTree.cn = vdomTree.cn.map((child, index) =>
322-
this.processVdomForComponents(child, parentId, index)
333+
me.processVdomForComponents(child, parentId, index)
323334
)
324335
}
325336

326337
return vdomTree
327338
}
339+
340+
/**
341+
* Change multiple configs at once, ensuring that all afterSet methods get all new assigned values
342+
* @param {Object} values={}
343+
* @param {Boolean} silent=false
344+
* @returns {Promise<*>}
345+
*/
346+
set(values={}, silent=false) {
347+
let me = this;
348+
349+
me.silentVdomUpdate = true;
350+
351+
super.set(values);
352+
353+
me.silentVdomUpdate = false;
354+
355+
if (silent || !me.needsVdomUpdate) {
356+
return Promise.resolve()
357+
}
358+
359+
return me.promiseUpdate()
360+
}
328361
}
329362

330363
export default Neo.setupClass(FunctionalBase);

0 commit comments

Comments
 (0)