observing of props in useEffect is inconsistent with component rendering
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.6k
- Forks
- 427
- Avg merge
- 10h 44m
- Merged PRs (30d)
- 18
Description
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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided Test and Root reproduction and compare the props read in the template with the read inside useEffect. Trace how props, signal, proxy, and rendering interact; done means the inconsistency is resolved or the supported reactive-props behavior is clearly established and covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100