Getting the warning "You have opted-out of Automatic Static Optimization due to getInitialProps
in pages/_app
." However there isn't any getInitialProps in our custom _app.js
import React from 'react'
import App from 'next/app'
// REDUX imports
import { Provider } from 'react-redux'
import withReduxStore from './../src/redux/with-redux-store'
// CONTEXT imports
import DeviceTypeContextProvider from './../src/contexts/device-type-context-provider';
// LOCAL imports
import Layout from './../src/components/common/layout'
class MyApp extends App {
render() {
const { Component, pageProps, reduxStore } = this.props
return (
<Provider store={reduxStore}>
<DeviceTypeContextProvider>
<Layout>
<Component {...pageProps} />
</Layout>
</DeviceTypeContextProvider>
</Provider>
)
}
}
export default withReduxStore(MyApp)
No warnings when no GIP is present in custom _app.js
Not sure what is triggering this warning, as in the error description
Could this also be the reason the static files are getting 404ed?
So, after digging up more I realised there is a GIP present in the withReduxStore HOC. My bad.
So is there no way to get nextjs with redux working and get Automatic Static Optimisation? I don't see a way to remove getInitialProps
from the code below and still get redux to work,
Ready to close the issue but still looking for some feedback/insight on this.
with-redux-store.js
import React from 'react'
import { initializeStore } from './store'
const isServer = typeof window === 'undefined'
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__'
function getOrCreateStore (initialState) {
// Always make a new store if server, otherwise state is shared between requests
if (isServer) {
return initializeStore(initialState)
}
// Create store if unavailable on the client and set it on the window object
if (!window[__NEXT_REDUX_STORE__]) {
window[__NEXT_REDUX_STORE__] = initializeStore(initialState)
}
return window[__NEXT_REDUX_STORE__]
}
export default App => {
return class AppWithRedux extends React.Component {
static async getInitialProps (appContext) {
// Get or Create the store with `undefined` as initialState
// This allows you to set a custom default initialState
const reduxStore = getOrCreateStore()
// Provide the store to getInitialProps of pages
appContext.ctx.reduxStore = reduxStore
let appProps = {}
if (typeof App.getInitialProps === 'function') {
appProps = await App.getInitialProps(appContext)
}
return {
...appProps,
initialReduxState: reduxStore.getState()
}
}
constructor (props) {
super(props)
this.reduxStore = getOrCreateStore(props.initialReduxState)
}
render () {
return <App {...this.props} reduxStore={this.reduxStore} />
}
}
}
Actually there is a solution for this. When I worked on the examples/with-redux I thought about this and added an undocumented ssr
option to the withRedux
hook 馃榿.
First check out the examples/with-redux. (Other redux example might not have this option, yet.)
Then apply the following changes to examples/with-redux/pages/index.js:
import React from 'react'
import { useDispatch } from 'react-redux'
import { withRedux } from '../lib/redux'
import useInterval from '../lib/useInterval'
import Clock from '../components/clock'
import Counter from '../components/counter'
const IndexPage = () => {
// Tick the time every second
const dispatch = useDispatch()
useInterval(() => {
dispatch({
type: 'TICK',
light: true,
lastUpdate: Date.now()
})
}, 1000)
return (
<>
<Clock />
<Counter />
</>
)
}
- IndexPage.getInitialProps = ({ reduxStore }) => {
- // Tick the time once, so we'll have a
- // valid time before first render
- const { dispatch } = reduxStore
- dispatch({
- type: 'TICK',
- light: typeof window === 'object',
- lastUpdate: Date.now()
- })
- return {}
- }
-
- export default withRedux(IndexPage)
+ export default withRedux(IndexPage, {
+ ssr: false
+ })
We disabled redux on the server-side here. This means your redux store will only have it's initial state when Next.js renders your components on the server. As soon as the client hydrated on the client, your app will get the right state.
| ssr: true
| ssr: false
|
|------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
| |
|
| automatic static optimization: disabled | automatic static optimization: enabled |
Thanks to Next.js you as a developer can now decide, what page of yours should use which strategy.
Please note that every strategy has it's ups and downsides.
The withApollo
example has the same option 馃.
Thank you so much @HaNdTriX for the detailed response.
So, to get the redux working with Automatic Static Optimization I'll have to let go of SSR. That's some trade off. Will try both approaches and see which one makes more sense to us. Thanks again.
Also do you this static files getting 404ed is somehow connected to this?
Closing as the initial issue appears to resolved
Most helpful comment
Actually there is a solution for this. When I worked on the examples/with-redux I thought about this and added an undocumented
ssr
option to thewithRedux
hook 馃榿.Example
First check out the examples/with-redux. (Other redux example might not have this option, yet.)
Then apply the following changes to examples/with-redux/pages/index.js:
Explanation
We disabled redux on the server-side here. This means your redux store will only have it's initial state when Next.js renders your components on the server. As soon as the client hydrated on the client, your app will get the right state.
Comparison
|
|
|
ssr: true
|ssr: false
||------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
|
| automatic static optimization: disabled | automatic static optimization: enabled |
Thanks to Next.js you as a developer can now decide, what page of yours should use which strategy.
Bonus
The
withApollo
example has the same option 馃.