Next.js: Loosing getInitialProps in HOC

Created on 26 Feb 2018  路  4Comments  路  Source: vercel/next.js

Hey :)
I have really simple styled-components HOC provider.

import React from 'react'
import { ThemeProvider } from 'styled-components'
import { theme } from 'common/globalStyles'


const withTheme = WrappedComponent => props => (
  <ThemeProvider theme={theme}>
    <WrappedComponent {...props} />
  </ThemeProvider>
)

export default withTheme

Then I have custom _error.js page component wrapped in withThemeProvider hoc.

import React from 'react'
import { withThemeProvider } from 'hocs'


class Error extends React.Component {
  static getInitialProps({ res, err }) {
    const statusCode = res ? res.statusCode : err ? err.statusCode : null;
    return { statusCode }
  }

  render() {
    return (
      <p>
        {this.props.statusCode
          ? `An error ${this.props.statusCode} occurred on server`
          : 'An error occurred on client'}
      </p>
    )
  }
}

export default withThemeProvider(Error)

getInitialProps is not getting called. Can you please help me fix it? :)

Most helpful comment

Try using the hoistNonReactStatics package https://github.com/mridgway/hoist-non-react-statics

All 4 comments

Try using the hoistNonReactStatics package https://github.com/mridgway/hoist-non-react-statics

Or provide getInitialProps in the HOC 馃憤

@shane805 Thank for your answer. That library is perfect. :) I did not want to create anything on my own because I was almost sure there must be perfect solution already available.

This is my withThemeProvider now (I will extract the hoistStatics in the future):

import React from 'react'
import { ThemeProvider } from 'styled-components'
import { theme } from 'common/globalStyles'
import hoistNonReactStatics from 'hoist-non-react-statics';


const withTheme = WrappedComponent => props => (
  <ThemeProvider theme={theme}>
    <WrappedComponent {...props} />
  </ThemeProvider>
)

const hoistStatics = higherOrderComponent => BaseComponent => {
  const NewComponent = higherOrderComponent(BaseComponent)
  hoistNonReactStatics(NewComponent, BaseComponent)
  return NewComponent
}

export default hoistStatics(withTheme)

Note that it's much better to not use hoist-non-react-statics, it's huge for what it does: https://bundlephobia.com/[email protected]

You can manually copy the getInitialProps, which is what you generally want anyway:

import React from 'react'
import { ThemeProvider } from 'styled-components'
import { theme } from 'common/globalStyles'

function withTheme(WrappedComponent) {
 function Theme (props) {
   return (
      <ThemeProvider theme={theme}>
        <WrappedComponent {...props} />
      </ThemeProvider>
    )
  }

  if(WrappedComponent.getInitialProps) {
    Theme.getInitialProps = WrappedComponent.getInitialProps
  } 

  return Theme
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

olifante picture olifante  路  3Comments

flybayer picture flybayer  路  3Comments

havefive picture havefive  路  3Comments

knipferrc picture knipferrc  路  3Comments

wagerfield picture wagerfield  路  3Comments