imp: add componentDidUpdate hook

This commit is contained in:
Géry Debongnie
2019-04-01 15:42:24 +02:00
parent e7a4ad99de
commit 990a08dc04
2 changed files with 71 additions and 3 deletions
+16 -3
View File
@@ -149,6 +149,16 @@ export class Component<
*/ */
mounted() {} mounted() {}
/**
* This hook is called whenever a component did actually update its props,
* state or env.
*
* 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 updated.
*/
componentDidUpdate() {}
/** /**
* willUnmount is a hook that is called each time a component is detached from * willUnmount is a hook that is called each time a component is detached from
* the DOM. This is a good place to remove some listeners, for example. * the DOM. This is a good place to remove some listeners, for example.
@@ -281,8 +291,9 @@ export class Component<
} }
Object.assign(this.env, nextEnv); Object.assign(this.env, nextEnv);
if (this.__widget__.isMounted) { if (this.__widget__.isMounted) {
return this.render(true); await this.render(true);
} }
this.componentDidUpdate();
} }
async updateProps( async updateProps(
@@ -312,8 +323,9 @@ export class Component<
} }
Object.assign(this.state, nextState); Object.assign(this.state, nextState);
if (this.__widget__.isStarted) { if (this.__widget__.isStarted) {
return this.render(); await this.render();
} }
this.componentDidUpdate();
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -322,7 +334,8 @@ export class Component<
async _updateProps(nextProps: Props): Promise<void> { async _updateProps(nextProps: Props): Promise<void> {
this.props = nextProps; this.props = nextProps;
return this.render(); await this.render();
this.componentDidUpdate();
} }
_patch(vnode) { _patch(vnode) {
+55
View File
@@ -387,6 +387,61 @@ describe("lifecycle hooks", () => {
]); ]);
}); });
test("componentDidUpdate hook is called after updateState", async () => {
let n = 0;
class TestWidget extends Widget {
state = { a: 1 };
componentDidUpdate() {
n++;
}
}
const widget = new TestWidget(env);
await widget.mount(fixture);
expect(n).toBe(0);
await widget.updateState({}); // empty update, should do nothing
expect(n).toBe(0);
await widget.updateState({ a: 3 });
expect(n).toBe(1);
});
test("componentDidUpdate hook is called after updateProps", async () => {
let n = 0;
class TestWidget extends Widget {
componentDidUpdate() {
n++;
}
}
const widget = new TestWidget(env, { a: 1 });
await widget.mount(fixture);
expect(n).toBe(0);
await widget.updateProps({ a: 2 });
expect(n).toBe(1);
});
test("componentDidUpdate hook is called after updateEnv", async () => {
let n = 0;
class TestWidget extends Widget {
state = { a: 1 };
componentDidUpdate() {
n++;
}
}
const widget = new TestWidget(env);
await widget.mount(fixture);
expect(n).toBe(0);
await widget.updateEnv({ isMobile: true });
expect(n).toBe(1);
});
test("shouldUpdate hook prevent rerendering", async () => { test("shouldUpdate hook prevent rerendering", async () => {
let shouldUpdate = false; let shouldUpdate = false;
class TestWidget extends Widget { class TestWidget extends Widget {