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

Eventually support/use multiple React roots? #50

Closed
ericf opened this issue Oct 25, 2016 · 12 comments
Closed

Eventually support/use multiple React roots? #50

ericf opened this issue Oct 25, 2016 · 12 comments

Comments

@ericf
Copy link
Contributor

ericf commented Oct 25, 2016

I noticed that one React root is used, while this is certainly the simplest solution, I'm curious if there's a plan to support or use multiple React roots?

In the current architecture with a single root, a client-side navigation blows away everything visible on the page and re-renders everything for the new route, including parts of the component tree that exist on both routes.

With multiple React roots, common site elements like a <header> could be in their own React root, and when the same page "region" exists between two routes the component tree won't need to be torn down and re-rendered during that client-side navigation. An architecture with multiple roots/regions would also allow the server to flush out to the response before waiting for the entire page to be rendered.

I imagine that when using Next, it'll be natural to break out common page-level UI component trees, like the site's header, and reuse it on all pages, similar to an "include", and at these page "region" boundaries there's an opportunity to use multiple React roots to speed up both server and client rendering.

So I'm mainly curious if this sort of thing might be part of Next in the future, or if the simplicity of one React root and re-rendering the entire page on client-side navigation is an explicit design decision for the framework?

@dlindenkreuz
Copy link
Contributor

dlindenkreuz commented Oct 26, 2016

Using more than one React root is a rather unusual solution to this problem. Did you test if Next.js routing actually prevents reconciliation and thus, common elements like a shared <Navigation> are forcibly re-rendered?

@dlindenkreuz
Copy link
Contributor

In the issue #88, I suggest having an editable top-level App container where these common elements could reside. This could be a solution to your problem as well.

@mmmeff
Copy link

mmmeff commented Oct 26, 2016

@dlindenkreuz I think that's the simplest solution here and fits this projects' philosophy best.

@ericf
Copy link
Contributor Author

ericf commented Oct 26, 2016

@dlindenkreuz Currently, Next eschews React's reconciler during client-side navigation and re-renders the entire dev-prodvided tree. This is because the of how React's reconciler works w.r.t. a component's type and key and Next's approach to "page" components.

It would be possible to use the same top-level page component by always exporting it from all your ./pages/*.js files, but if you want to implement getInitialProps(), you'd need to re-implement routing so you can run the right logic for the current router/url since getInitialProps() would be a static method shared for all pages.

Another reason I'm bringing up multiple React roots is to support HTTP response streaming that doesn't have to wait for the entire tree to render. I think there's a reasonable middle ground where the dev can provide the app shell (as you're suggesting), and Next does some intelligent rendering (possibly using multiple roots) to allow server response streaming and client-side component instance reuse.

@mmmeff
Copy link

mmmeff commented Oct 26, 2016

Here's a link to an example I built that shows how you can re-use a single definition of your layout across all your pages without repeating any code. https://github.com/mmmeff/nextjs-page-template-example

@ericf
Copy link
Contributor Author

ericf commented Oct 26, 2016

@mmmeff I'm not talking about reuse at the coding level, I'm talking about component instance reuse at the React reconciler level during runtime in the browser. What you have will still be entirely torn down between client-side navigations because index.js and about.js export different React component types.

https://facebook.github.io/react/docs/reconciliation.html#the-diffing-algorithm

@mmmeff
Copy link

mmmeff commented Oct 26, 2016

@ericf Well aware (and listed it as a caveat in my readme). Any ideas on potential workarounds though?

@ericf
Copy link
Contributor Author

ericf commented Oct 26, 2016

@mmmeff a simple solution would be something like @dlindenkreuz suggested with Next allowing the dev to customize the app component which remains the same instance across client-side navigations. The conceptual model would be similar to your example where you create an "app shell".

@dlindenkreuz
Copy link
Contributor

dlindenkreuz commented Oct 27, 2016

Another reason I'm bringing up multiple React roots is to support HTTP response streaming that doesn't have to wait for the entire tree to render

@ericf Wow, I honestly never thought this was possible. Can you recommend me some articles to read up on that?

A customizable top-level App component would probably solve this in the simple way the project is aiming at. Having multiple roots sounds like a low-level conceptual decision (even though I'm not yet enlightened what this is all about 😀) which should either be left up to the user or which has to be done by Next.js in an elegant, unobtrusive way.

This was referenced Oct 27, 2016
@ericf
Copy link
Contributor Author

ericf commented Oct 27, 2016

Can you recommend me some articles to read up on that?

@dlindenkreuz check out: https://react-server.io

which should either be left up to the user or which has to be done by Next.js in an elegant, unobtrusive way.

Yeah, I'm thinking about it in terms of a Next implementation detail that the dev isn't concerned with.

@sedubois
Copy link
Contributor

sedubois commented Nov 1, 2016

+1 for having a way for the user to maintain state across pages (not necessarily with multiple roots though), for shared navigation elements with their CSS transitions, and also for Redux and GraphQL clients such as Apollo. Maintaining the state in window (as currently suggested for Redux in the Wiki and explored for Apollo in #106) feels more complex than it might need to be?

@arunoda
Copy link
Contributor

arunoda commented Dec 2, 2016

Guys, with v1.2.x now we can share modules between pages. Now if a module used by all of the pages, it'll be move into the commons.js.

Eventually, we'll add support tuning options.

About the multiple react-roots, it's kind a questionable. Not sure we'll do it by default.
But you will be able to do that once we support this: #251.

I am closing this issue because I think we are clear on this topic. But feel free to reopen if you are looking for something different.

@arunoda arunoda closed this as completed Dec 2, 2016
@lock lock bot locked as resolved and limited conversation to collaborators May 12, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants