[IMP] reactivity: new primitives for reactivity

fine grained reactivity:

existing key in source changes --> only observer having read the key are notified

add/delete key in source changes --> all source observers are notified

Co-authored-by: Aaron Bohy <aab@odoo.com>
Co-authored-by: Géry Debongnie <ged@odoo.com>
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
This commit is contained in:
Mathieu Duckerts-Antoine
2021-10-26 14:51:57 +02:00
committed by Géry Debongnie
parent 6479631983
commit 4e4b85e2a9
6 changed files with 604 additions and 372 deletions
@@ -594,10 +594,11 @@ exports[`lifecycle hooks patched hook is called after updating State 1`] = `
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue } = helpers;
let block1 = createBlock(\`<div/>\`);
let block1 = createBlock(\`<div><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
let d1 = ctx['state'].a;
return block1([d1]);
}
}"
`;
@@ -15,6 +15,21 @@ exports[`reactivity in lifecycle can use a state hook 1`] = `
}"
`;
exports[`reactivity in lifecycle can use a state hook 2 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let d1 = ctx['state'].a;
return block1([d1]);
}
}"
`;
exports[`reactivity in lifecycle change state while mounting component 1`] = `
"function anonymous(bdom, helpers
) {
+1 -1
View File
@@ -493,7 +493,7 @@ describe("lifecycle hooks", () => {
let n = 0;
class Test extends Component {
static template = xml`<div/>`;
static template = xml`<div><t t-esc="state.a"/></div>`;
state = useState({ a: 1 });
setup() {
+22
View File
@@ -31,6 +31,28 @@ describe("reactivity in lifecycle", () => {
expect(fixture.innerHTML).toBe("<div>3</div>");
});
test("can use a state hook 2", async () => {
let n = 0;
class Comp extends Component {
static template = xml`<div><t t-esc="state.a"/></div>`;
state = useState({ a: 5, b: 7 });
setup() {
onRender(() => n++);
}
}
const comp = await mount(Comp, fixture);
expect(fixture.innerHTML).toBe("<div>5</div>");
expect(n).toBe(1);
comp.state.a = 11;
await nextTick();
expect(fixture.innerHTML).toBe("<div>11</div>");
expect(n).toBe(2);
comp.state.b = 13;
await nextTick();
expect(fixture.innerHTML).toBe("<div>11</div>");
expect(n).toBe(2); // no new rendering occured: b was never read via state!
});
test("state changes in willUnmount do not trigger rerender", async () => {
const steps: string[] = [];
class Child extends Component {