@timeout
Runs a method once, ms after the component mounts. If the component is removed first, it never
runs.
The situation it is for
A confirmation that fades itself out. It appears when something succeeded, and it has to disappear four seconds later — unless the reader navigates away first, in which case the timer must not outlive the page it belongs to:
class Toast extends Component<{ message: string }> {
@state shown = true;
@timeout(4000)
hide() {
this.shown = false;
}
render() {
return this.shown ? <p role="status">{this.props.message}</p> : null;
}
}
That cancellation is the point. A raw setTimeout whose callback writes state after the component
is gone is reported as RMD008 — the write is dropped and the
render it asked for never happens.
What it refuses
The delay is checked where it is written, at class-definition time, and by exactly the rules
@interval uses: a number, finite, not negative, and at most
2,147,483,647 ms — beyond which setTimeout truncates and the callback fires immediately
instead of late.
Anything but a method.
What it costs, and when not to reach for it
It starts at mount and only at mount. A delay that begins when something happens — a click, a
response — is the Timeout hook instead, which you start and stop yourself:
class Confirm extends Component {
private undo = this.use(Timeout, () => ({ run: this.commit }));
askedFor() {
this.undo.start(5000);
}
cancel() {
this.undo.stop();
}
commit() {}
}
It is browser-only, for the same reason as @interval: both
are built on the effect primitive, and effects never run during a server render.