Gabriel Cséfalvay
Gabriel Cséfalvay

Reputation: 539

Getting a 'Hydration mismatch' when using splitProps in SolidStart/SolidJS

I'm getting a hydration mismatch error for this code, and I don't really understand why.

Hydration Mismatch. Unable to find DOM nodes for hydration key: 00000000100...
and indicating the child of this component

Here is a minimal code sample:

export function Button(props) {
    const [specialProps, passedProps] = splitProps(props, [
        "class",
        "children",
        "disabled",
        "leftIcon",
    ]);

    const buttonCva = cva("btn", {
        variants: {
            disabled: {
                true: "btn-disabled",
            },
        },
    });

    return (
        <button class={buttonCva(specialProps)} {...passedProps}>
            {specialProps.leftIcon}
            {specialProps.children}
        </button>
    );
}

What I figured out so far is that if I remove "children" from specialProps (so it will be in passedProps), it works.

Upvotes: 0

Views: 35

Answers (1)

Gabriel Cs&#233;falvay
Gabriel Cs&#233;falvay

Reputation: 539

So I figured out what is the problem: Any elements that are generated during render, are then searched for in the DOM during hydration. In the code above, the children were rendered twice, because

  1. first, the buttonCva() function evaluated them (probably reading the whole specialProps object), and then,
  2. for the second time, {specialProps.children} evaluated them.

No. 2 got inserted into the DOM, but no. 1 just got discarded - so the hydration script on the client side couldn't find it anywhere in the DOM.


So here is the corrected code:

export function Button(props) {
    const [classProps, childrenProps, passedProps] = splitProps(props, [
        "class",
        "disabled",
    ],[
        "children",
        "leftIcon",
    ]);

    const buttonCva = cva("btn", {
        variants: {
            disabled: {
                true: "btn-disabled",
            },
        },
    });

    return (
        <button class={buttonCva(classProps)} {...passedProps}>
            {childrenProps.leftIcon}
            {childrenProps.children}
        </button>
    );
}

In hindsight, it's a silly mistake. But the hydration process and requirements of SolidStart is not that well documented so far.


Here is some reading that helped me:
Hydration error for rendered Elements that aren't inserted in the DOM during server rendering #1977
<Show when={JSX.Element} /> breaks SSR (causes Hydration Errors) #2345

Upvotes: 0

Related Questions