Next.js: [RFC] Move to React.createContext instead of ChildContext in Next.js core

Created on 20 Nov 2018  路  24Comments  路  Source: vercel/next.js

Feature request

Currently the core of Next.js uses the legacy React context API: https://reactjs.org/docs/legacy-context.html

This API currently poses no real issues on Next.js itself at this point, but will be removed in React 17. It also forces us to use/bundle the prop-types module because the legacy context API uses this to pass certain types.

Describe the solution you'd like

Changing to the React.createContext API will make the bundle size for any Next.js app smaller.

Downsides

The main downside to switching to React.createContext is that React alternatives like preact / inferno don't support it fully:

preact: https://github.com/developit/preact-compat/issues/475
Inferno: https://github.com/infernojs/inferno/issues/1299

Meaning that if we implement this we're essentially dropping support for React alternatives. However this will be the same case once React Hooks become stable and when the Suspense streaming renderer lands.

Additional context

I'd love to get community feedback on this.

p2

Most helpful comment

Yep, this one's on us.

All 24 comments

Don't Preact and Inferno always migrate to the new React API's after some time ?, I always saw those tools as React compatible.

Seems like if possible, be best to have it as a conditional then have a date for deprecation. I think no way to know how many people would be affected and deprecation is pretty standard in the industry.

Sounds like a Good Idea! Smaller bundle = big win.

The main question here seems to be - does Next.js need to support React alternatives.

Probably the answer is no.

Can't wait to see if/when Next embraces React Hooks!

@curran

Can't wait to see if/when Next embraces React Hooks!

You can already use react@alpha with hooks in Next.js, however, like the React team said, don't put it in production for mission critical things.

Don't Preact and Inferno always migrate to the new React API's after some time ?, I always saw those tools as React compatible.

Eg Fragments are not supported by default in preact: https://github.com/developit/preact/issues/946

So for reference:

next-preact has 300 downloads per week
next-css has 90K downloads per week

This is the right thing to do. React alternatives will need to maintain compatibility if they want to remain alternatives.

Yep, this one's on us.

Can we also use new Context API in App component? https://github.com/zeit/next.js/blob/canary/packages/next/pages/_app.js#L7

It's a breaking change and I still have to figure out how to solve it without breaking. The issue is that with-apollo and similar need the full tree to pre-render queries correctly.

@timneutkens The strategic used by Apollo will be removed once React Suspense for Data Fetching is out, and that is before React 17 馃憤

@lfades that'll take at least a couple of months.

@timneutkens Is there something I can do to help push this forward? Does this only come down to migrating internal usage or is this part of the public API?

This would help a lot with using StrictMode and unstable_ConcurrentMode. In its current state this adds a lot of noise from other libraries (next in this case).

It's already mostly implemented, only thing missing is router, but we need to find something to handle the apollo getDataFromTree.

Will it be possible to obtain values from context providers in getInitialProps?

When I wrap my app in <React.Strict /> I see this error in the console:

index.js:1 Warning: Legacy context API has been detected within a strict-mode tree: 
    in StrictMode (created by MyApp)
    in Container (created by MyApp)
    in MyApp (created by withApollo(App))
    in withApollo(App)

Please update the following components: withRouter(Header)

Learn more about this warning here:
https://fb.me/react-strict-mode-warnings

Is this error related to this issue?

Will it be possible to obtain values from context providers in getInitialProps?

It won't be possible, getInitialProps runs before React renders and it's a static method, I'd also argue that there is no need for React context in getInitialProps, I can't think of a valid use-case of it that isn't covered by composition.

Is this error related to this issue?

Yes as the issue is still open because we haven't moved everything, there's an issue around Apollo / similar solutions rendering the React tree.

Is this available yet on any other branches at this stage?

It's already mostly implemented, only thing missing is router, but we need to find something to handle the apollo getDataFromTree.

@timneutkens, can react-ssr-prepass be any help?

Not really as the prepass has to know the full tree too. @ijjk has opened a PR to provide the tree to be rendered, even though I'd rather not add that specifically there seems to be no way around it right now.

Prepass by itself won't be added to Next.js as it's a non-standard React renderer, so it breaks in some cases.

This has been solved by @devknoll in the latest stable Next.js version.

@timneutkens can you point to the PR? Also how was the compatibility with react alternatives handled?

@iamstarkov it was over multiple PRs, but you can search for author:devknoll as Gerald did most of them. There weren't any interopt needs as preact has createContext support now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

knipferrc picture knipferrc  路  3Comments

havefive picture havefive  路  3Comments

rauchg picture rauchg  路  3Comments

ghost picture ghost  路  3Comments

swrdfish picture swrdfish  路  3Comments