Skip to content

observing of props in useEffect is inconsistent with component rendering #1908

@seb-odoo

Description

@seb-odoo

The following example prints 1 then 2 in the console, but never 3.
The template does render 1 then 2 then 3 however.

We expect all read of this.props.o.val to be reactive in the same way, but it is not the case.

I understand the canonical way to proceed here would be to pass the signal as props instead of its return value.
But the example is still valid, and the inconsistency of props in terms of effect and rendering is highly problematic.

Because of this, onWillUpdateProps cannot be simply converted to equivalent useEffect, because callers need to provide a signal.

import { Component, mount, xml, props, types, useEffect, proxy, signal } from "@odoo/owl";

class Test extends Component {
    static template = xml`<span t-out="this.props.o.val"/>`;
    props = props(["o"]);
    setup() {
        useEffect(() => console.log(this.props.o.val));
    }
}

class Root extends Component {
    static template = xml`<div>Hello Owl!<Test o="this.obj()"/></div>`;
    static components = { Test };

    obj = signal(proxy({ val: 1 }));

    setup() {
        setTimeout(() => this.obj().val = 2, 100);
        setTimeout(() => this.obj.set(proxy({ val: 3 })), 200);
    }
}

mount(Root, document.body, { templates: TEMPLATES, dev: true });

Side remark, but I don't understand why props.signal="..." is not the default if the given value is not a signal. It seems extremely confusing and error prone to allow non-reactive values as props, but with just a little bit of magic to still trigger re-rendering. This is even more strange as .alike already exists for case where we would want to disable the auto-wrapping behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions