diff --git a/doc/component.md b/doc/component.md index 6ea4386e..4f68322b 100644 --- a/doc/component.md +++ b/doc/component.md @@ -139,15 +139,15 @@ A solid and robust component system needs useful hooks/methods to help developers write components. Here is a complete description of the lifecycle of a owl component: -| Method | Description | -| --------------------------------------- | --------------------------------------- | -| **[constructor](#constructor)** | constructor | -| **[willStart](#willStart)** | async, before first rendering | -| **[mounted](#mounted)** | when component is render and in DOM | -| **[willUpdateProps](#willUpdateProps)** | async, before props update | -| **[willPatch](#willPatch)** | just before the DOM is patched | -| **[patched](#patched)** | just after the DOM is patched | -| **[willUnmount](#willUnmount)** | just before removing component from DOM | +| Method | Description | +| ------------------------------------------------ | --------------------------------------- | +| **[constructor](#constructor)** | constructor | +| **[willStart](#willStart)** | async, before first rendering | +| **[mounted](#mounted)** | when component is render and in DOM | +| **[willUpdateProps](#willupdatepropsnextprops)** | async, before props update | +| **[willPatch](#willpatch)** | just before the DOM is patched | +| **[patched](#patchedsnapshot)** | just after the DOM is patched | +| **[willUnmount](#willUnmount)** | just before removing component from DOM | Note: no hook method should ever be called manually. They are supposed to be called by the owl framework whenever it is required. @@ -248,7 +248,10 @@ Note that modifying the state object is not allowed here. This method is called before an actual DOM patch, and is only intended to be used to save some local DOM state. -#### `patched()` +The return value of this method will be given as the first argument of the +corresponding `patched` call. + +#### `patched(snapshot)` This hook is called whenever a component did actually update its DOM (most likely via a change in its state/props or environment). @@ -257,6 +260,8 @@ This method is not called on the initial render. It is useful to interact with the DOM (for example, through an external library) whenever the component was patched. +The `snapshot` parameter is the result of the previous `willPatch` call. + Updating the widget state in this hook is possible, but not encouraged. One need to be careful, because updates here will cause rerender, which in turn will cause other calls to patched. So, we need to be particularly diff --git a/src/component.ts b/src/component.ts index 56d7635d..aa9366c0 100644 --- a/src/component.ts +++ b/src/component.ts @@ -160,8 +160,10 @@ export class Component< * It is not called on the initial render. This is useful to get some * information which are in the DOM. For example, the current position of the * scrollbar + * + * The return value of willPatch will be given to the patched function. */ - willPatch() {} + willPatch(): any {} /** * This hook is called whenever a component did actually update its props, @@ -175,8 +177,10 @@ export class Component< * One need to be careful, because updates here will cause rerender, which in * turn will cause other calls to updated. So, we need to be particularly * careful at avoiding endless cycles. + * + * The snapshot parameter is the result of the call to willPatch. */ - patched() {} + patched(snapshot: any) {} /** * willUnmount is a hook that is called each time just before a component is @@ -331,9 +335,9 @@ export class Component< _patch(vnode) { this.__owl__.renderPromise = null; if (this.__owl__.vnode) { - this.willPatch(); + const snapshot = this.willPatch(); this.__owl__.vnode = patch(this.__owl__.vnode, vnode); - this.patched(); + this.patched(snapshot); } else { this.__owl__.vnode = patch(document.createElement(vnode.sel!), vnode); } diff --git a/tests/component.test.ts b/tests/component.test.ts index 2ecf89ec..0be0d587 100644 --- a/tests/component.test.ts +++ b/tests/component.test.ts @@ -545,8 +545,10 @@ describe("lifecycle hooks", () => { state = { n: 1 }; willPatch() { steps.push("parent:willPatch"); + return 'leffe'; } - patched() { + patched(snapshot) { + expect(snapshot).toBe('leffe'); steps.push("parent:patched"); } }