Closed mairatma closed 8 years ago
Unfortunately, there's no good way to fix this. Because you've hoisted getDiv
outside render
, it'll be detected as a "root" rendering function (and it won't add a jsxWrapper
).
Possible solutions:
fastRoot
, which'll try to prioritize the side effects of iDOM over the semantics of JSX
getDom
. In this case, it's a "pure" JSX function, but it'd be pretty simple to write one that isn't.For reference, here's the (snipped) output with fastRoot: true
:
function getDiv() {
elementOpen("div");
text("Bottom");
return elementClose("div");
}
function render() {
elementOpen("div");
true && (elementOpen("div"), (elementOpen("div"), text("Top"), elementClose("div")), _renderArbitrary(getDiv()), elementClose("div"));
return elementClose("div");
}
Would it be possible to transform operations like ||
and &&
that are inside jsx elements into their if/else
equivalents? It could fix this kind of problem without cons (I think) :)
Possibly, as long as there's not a invoked function with JSX inside the conditional expression (madness!).
function check() {
return <why>do I do this?</why>
}
function render() {
return <root>
{true && check() && <tears />}
</root>;
}
Agreed, that could never work, it's not a supported use case.
It'd be worth doing this fix for the other cases though, which developers would expect to work.
So would something like this still be supported?
// Case A
function check(count) {
return count > 5;
}
function render(data) {
return <root>
{true && check(data.count) && <WowSoMany />}
</root>;
}
Or this:
// Case B
function renderMany(count) {
return <WowSoMany />;
}
function render(data) {
return <root>
{data.count > 5 && renderMany()}
</root>;
}
Yeah, I think both these cases you've mentioned already work today, btw, since the jsx function is not inside another element. This change would just make other cases work too.
Ah ok, cool. The reason I asked is it seemed like Case A above was what @jridgewell was describing:
as long as there's not a invoked function with JSX inside the conditional expression
So modifying Case B, this is what would be fixed, right?
function render(data) {
return <root>
{data.count > 5 && <div>{renderMany()}</div>}
</root>;
}
Exactly :)
Say you have some code like this:
After patching the element its contents should be:
But they end up being:
Looking at the compiled code, it seems like this is because it's calling
getDiv
before the right time, causing incremental dom to render it first:Removing the
{true && ...}
part everything works again, so it's something with conditionals + functions.