mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[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:
committed by
Aaron Bohy
parent
80cb6b7a91
commit
d3745e4e5f
@@ -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
|
||||
) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user