[FIX] useEffect: can depend on dom dependencies

Because the dependencies are now computed in patched.
This commit is contained in:
Géry Debongnie
2021-12-21 16:36:36 +01:00
committed by Aaron Bohy
parent 3c98ef8cb1
commit bd5637c0a3
3 changed files with 57 additions and 14 deletions
@@ -197,6 +197,25 @@ exports[`hooks useEffect hook dependencies prevent effects from rerunning when u
}"
`;
exports[`hooks useEffect hook effect can depend on stuff in dom 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let block2 = createBlock(\`<div block-ref=\\"0\\"/>\`);
return function template(ctx, node, key = \\"\\") {
const refs = ctx.__owl__.refs;
let b2;
if (ctx['state'].value) {
let d1 = (el) => refs[\`div\`] = el;
b2 = block2([d1]);
}
return multi([b2]);
}
}"
`;
exports[`hooks useEffect hook effect runs on mount, is reapplied on patch, and is cleaned up on unmount and before reapplying 1`] = `
"function anonymous(bdom, helpers
) {
+32 -3
View File
@@ -17,7 +17,7 @@ import {
useSubEnv,
xml,
} from "../../src/index";
import { elem, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
import { elem, logStep, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
let fixture: HTMLElement;
@@ -396,6 +396,35 @@ describe("hooks", () => {
]);
});
test("effect can depend on stuff in dom", async () => {
class MyComponent extends Component {
static template = xml`
<t t-if="state.value">
<div t-ref="div"/>
</t>`;
state = useState({
value: false,
});
setup() {
const ref = useRef("div");
useEffect(
(el) => {
logStep("effect started:" + (el ? "EL" : "NULL"));
return () => logStep("cleaning up effect:" + (el ? "EL" : "NULL"));
},
() => [ref.el]
);
}
}
const component = await mount(MyComponent, fixture);
expect(["effect started:NULL"]).toBeLogged();
component.state.value = true;
await nextTick();
expect(["cleaning up effect:NULL", "effect started:EL"]).toBeLogged();
});
test("dependencies prevent effects from rerunning when unchanged", async () => {
let steps = [];
class MyComponent extends Component {
@@ -455,22 +484,22 @@ describe("hooks", () => {
"before state mutation: a",
// Cleanups run in reverse order
"cleaning up for ab: {a: 0, b: 0}",
// Cleanup for b is not run
"cleaning up for a: 0",
"Effect a: 1",
"cleaning up for ab: {a: 0, b: 0}",
// Effect b is not run
"Effect ab: {a: 1, b: 0}",
"after state mutation: a",
"before state mutation: b",
"cleaning up for ab: {a: 1, b: 0}",
"cleaning up for b: 0",
// Cleanup for a is not run
// Effect a is not run
"Effect b: 1",
"cleaning up for ab: {a: 1, b: 0}",
"Effect ab: {a: 1, b: 1}",
"after state mutation: b",