mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[FIX] component: render in delayed willUpdateProps
Have a child component on which a render is triggered. This component delays its willUpdateProps and makes a rendering during the willUpdateProps Before this commit, renderings of the child were inconsistent across its parent's renderings. After this commit, it works as expected.
This commit is contained in:
committed by
Aaron Bohy
parent
6f435c36d8
commit
894deed13b
@@ -203,12 +203,6 @@ export class ComponentNode<T extends typeof Component = typeof Component>
|
||||
// update
|
||||
const fiber = makeChildFiber(this, parentFiber);
|
||||
this.fiber = fiber;
|
||||
if (this.willPatch.length) {
|
||||
parentFiber.root.willPatch.push(fiber);
|
||||
}
|
||||
if (this.patched.length) {
|
||||
parentFiber.root.patched.push(fiber);
|
||||
}
|
||||
const component = this.component;
|
||||
applyDefaultProps(props, component.constructor as any);
|
||||
const prom = Promise.all(this.willUpdateProps.map((f) => f.call(component, props)));
|
||||
@@ -216,8 +210,15 @@ export class ComponentNode<T extends typeof Component = typeof Component>
|
||||
if (fiber !== this.fiber) {
|
||||
return;
|
||||
}
|
||||
this.component.props = props;
|
||||
component.props = props;
|
||||
this._render(fiber);
|
||||
const parentRoot = parentFiber.root;
|
||||
if (this.willPatch.length) {
|
||||
parentRoot.willPatch.push(fiber);
|
||||
}
|
||||
if (this.patched.length) {
|
||||
parentRoot.patched.push(fiber);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+30
-1
@@ -3,15 +3,44 @@ import type { ComponentNode } from "./component_node";
|
||||
import { fibersInError, handleError } from "./error_handling";
|
||||
import { STATUS } from "./status";
|
||||
|
||||
/**
|
||||
* Cleans on the root fiber the patch and willPatch fiber lists
|
||||
* It is typically needed when the same root fiber needs to recycle on
|
||||
* of its children or grandchildren's fiber.
|
||||
*/
|
||||
function cleanPatchableFiber(child: Fiber, root: RootFiber) {
|
||||
const { willPatch, patched } = root;
|
||||
let i = willPatch.indexOf(child);
|
||||
if (i > -1) {
|
||||
willPatch.splice(i, 1);
|
||||
}
|
||||
i = patched.indexOf(child);
|
||||
if (i > -1) {
|
||||
patched.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
export function makeChildFiber(node: ComponentNode, parent: Fiber): Fiber {
|
||||
let current = node.fiber;
|
||||
if (current) {
|
||||
// current is necessarily a rootfiber here
|
||||
let root = parent.root;
|
||||
const isSameRoot = current.root === root;
|
||||
cancelFibers(root, current.children);
|
||||
current.children = [];
|
||||
current.parent = parent;
|
||||
root.counter++;
|
||||
// only increment our rendering if we were not
|
||||
// already accounted for, or that we have been rendered
|
||||
// already (in which case our fiber was removed from the root rendering)
|
||||
if (!isSameRoot || current.bdom) {
|
||||
root.counter++;
|
||||
}
|
||||
|
||||
if (isSameRoot) {
|
||||
cleanPatchableFiber(current, root);
|
||||
}
|
||||
|
||||
current.bdom = null;
|
||||
current.root = root;
|
||||
return current;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user