Skip to content
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

Make withHydrate a no-op when nested rather than an error #148

Open
ratorx opened this issue Mar 21, 2021 · 0 comments
Open

Make withHydrate a no-op when nested rather than an error #148

ratorx opened this issue Mar 21, 2021 · 0 comments

Comments

@ratorx
Copy link
Contributor

ratorx commented Mar 21, 2021

Currently withHydrate detects when it is used on the child element of a hydrated parent and errors. Instead of this, I think it might be better to do nothing (just return the component, don't create the hydration marker). This doesn't change the API, but removes a restriction.

Doing this makes withHydrate more composable. Right now, when creating a child component, you need to worry about whether it's should be the root a hydration tree or not. Ideally, you wouldn't have to do this - you could write components and tag them with withHydrate if they should be hydrated and have the framework automatically determine good hydration roots. I think just ignoring the nested withHydrate achieves this. Children are hydrated as expected (because their parent has a withHydrate) and parents don't have to worry about whether their children are hydrated or not.

Example code (which is not as easily possible today)

components/button.tsx:

const SimpleButton: FunctionalComponent<{classNames: string[]}> = (props) => <button class={props.classNames} onClick={() => alert("Test")}/>Test</button>;
export default withHydrate(SimpleButton);

components/multiple.tsx:

const MultipleButtons = (_: {}) => {
	const [s, setS] = useState(false);
	return <><button onClick={() => setS((s) => !s)}>Change colour</button><SimpleButton classNames={s ? ["red"] : ["blue"]} /></>
}

export default withHydrate(MultipleButtons)

pages/index.tsx:

const Index = (_: {}) => <main><SimpleButton classNames={[]}/><MultipleButtons /></main>

export default definePage(Index);

In this case, SimpleButton is both a root of a hydrated tree (in one context) and a child of a hydrated parent (in a different one). To make this work now, you'd have to export SimpleButton as both a hydrated export and a regular export. If withHydrate ignored children, then only 1 export is enough to make this work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant