Do m.redraw() and m.redraw.sync() actually work?
EverettMcKay opened this issue · comments
Mithril.js version:
using mithril: 2.2.2
I have a react background and have been using Mithril for a couple projects lately. Love the simplicity and conciseness of the code. Overall very pleased.
But with one glaring exception: I have probably tried using m.redraw() in about 20 different circumstances, and so far I'm 0 for 20. There is a state change, but redraw never shows it.
Code
To provide a bit of code, suppose I have a component that looks like this:
let state = false;
const SomeComponent= () => {
return {
view: () => {
if (state) return <p>State is set</p>;
return <p>State is not set</p>;
},
};
};
Expected Behavior
If clicking a button changes state (perhaps after a server call), the component should refresh and if not, m.redraw should force it, right? But it never works...and is very frustrating. Placing a breakpoint in the view function shows that the component is never rerendered, with or without the m.redraw.
By contrast, forcing a redraw with something like m.render(document.body, getBody()) works every time, but I assume is probably not a good idea. I'm using that a lot now to avoid wasting time but it seems wrong.
Question
Is there a trick to getting ordinary state changes after interaction to redraw components?
(In React, the answer to this question is to use UseState and unique keys for iterables.)
Hello m.render
(no autoredraw) vs. m.mount
(autoredraw)?
Here's an example.
@osban got there first, I was about to suggest the same.
Here's the example I cobbled together, using JSX since this is what @EverettMcKay uses. When creating a flems from scratch, you must toggle Babel for the .js
file in the hamburger menu, and set the pragmas.
That's it. Brilliant! Thanks!
A console message that explains any futile m.redraw() calls (and what to do instead) would earn a gold star.
@EverettMcKay good point, we could emit a warning if it is called when no reactive root have been defined.