-
-
Notifications
You must be signed in to change notification settings - Fork 926
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug?]: hydration mismatch on ssr, and nested ternaries in jsx with objects or signals #2100
Comments
I have no idea how you narrowed this down. But I'm impressed. |
I'm going to move this to Solid.. I'm about 99% sure this is a compilation mismatch error. |
I can repro here:
I can't repro here:
|
I think I've figured why the error doesn't repro in the solid-ssr examples as i expected: It only shows up in dev mode, and they only have build/start. For both astro, vinxi, solid-start I don't see the error when previewing a production build. |
@birkskyum the only common thing between the three is that they are in SSR and they use the Vite plugin. |
Alright, if I remove the dev-only flag in dom-expressions for the Hydration Mismatch error, then I can repro with the solid-ssr example as well - without the vite-plugin-solid. It's a bit easier to debug. |
This appear to be a bug in babel-plugin-jsx-dom-expressions |
function Comp (){
const obj1 = {
prop: true,
};
const obj2 = {
prop: true,
};
return <>{obj1.prop ? obj2.prop ? <span>4</span> : <></> : <></>}</>;
} Compiles to this: function App() {
const obj1 = {
prop: true
};
const obj2 = {
prop: true
};
return _$memo((() => {
const _c$ = _$memo(() => !!obj1.prop);
return () => _c$() ? (() => {
const _c$2 = _$memo(() => !!obj2.prop);
-- // Current / Wrong
-- return () => _c$2() ? _$getNextElement(_tmpl$) : [];
++ // Correct
++ return _c$2() ? _$getNextElement(_tmpl$) : [];
})() : [];
})());
} or potentially less aggressively memoized
|
ExplanationSeems like the wrapping memo is lacking a "() =>", and every memo inside has an extra. Therefore (inline syntax for clarity) 0 x obj1.prop - this works<>{_$getNextElement(_tmpl$)}</> Result return getNextElement(_tmpl$); 1 x obj.prop - this works, accidentally<>{ obj1.prop ? _$getNextElement(_tmpl$) : [] }</> Result return createMemo( // Missing "() =>" from the wrapper
() => (createMemo(() => !!obj1.prop)() ? getNextElement(_tmpl$) : []) // inserted per obj1.prop
); here we see the wrapper isn't a function, but fortunately there is an extra return createMemo(() => // Rely on the "() =>" from below line
(createMemo(() => !!obj1.prop)() ? getNextElement(_tmpl$) : [])
); 2 x obj.prop<>{ obj1.prop ? obj1.prop ? _$getNextElement(_tmpl$) : [] : [] }</> Result return createMemo( // Missing "() =>" from the wrapper
() => (createMemo(() => !!obj1.prop)() ?
() => (createMemo(() => !!obj1.prop)() ? getNextElement(_tmpl$) : []) // inserted per obj1.prop
// ^ this "()=>" should not be here as the function is never invokes. the effect is that "getNextElement" never get's called
: [])
); this is where things start to go sideways. The outermost memo still accidentally pairs with the It only get's worse when nesting further, as an extra uncalled Solutionan extra Result -- return createMemo(
++ return createMemo(() =>
-- () => (createMemo(() => !!obj1.prop)() ? getNextElement(_tmpl$) : []) // inserted per obj1.prop
++ (createMemo(() => !!obj1.prop)() ? getNextElement(_tmpl$) : []) // inserted per obj1.prop
); OutcomeNow every added wrapping of getNextElement(_tmpl$) with the green line above: (createMemo(() => !!obj1.prop)() ? getNextElement(_tmpl$) : []) |
Hmm.. I wonder if I did this for a reason. But didn't reflect it in SSR. The one thing that returning the function does is isolate the execution.. however returning a non-memoized function seems weird. So this is probably my mistake. There was a compilation issue where we were hoisting up the memo outside of the prop getter. I changed the behavior then. I'd love to track that down. |
Duplicates
Latest version
Current behavior 😯
With SSR, this gives a hydration error:
The error also exist with signals instead of plain objects
The error is:
Expected behavior 🤔
I expected this to work, like it does with
ssr:false
.The code also runs fine if I replace this:
With anything else really..
Steps to reproduce 🕹
Steps:
Here is a stackblitz:
Context 🔦
No response
Your environment 🌎
No response
The text was updated successfully, but these errors were encountered: