I am building my first Next.js site with Redux and I am running into a problem with the error:
Error: could not find react-redux context value; please ensure the component is wrapped in a
I am using _document.js to create 'template' for my site, which includes a header and footer:
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { PublicHeader, Footer } from '../components';
class Public extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html>
<Head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin />
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&family=Poppins:wght@300;400;600;700;800&display=swap" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" />
<script src="https://kit.fontawesome.com/aa1831f3ef.js" crossOrigin="anonymous"></script>
</Head>
<body>
<PublicHeader />
<Main />
<Footer />
<NextScript>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossOrigin="anonymous"></script>
</NextScript>
</body>
</Html>
)
}
}
export default Public
I have Redux set up with a store and then I wrapped the _app.js with the Provider.
import '../styles/css/main.css';
import { useStore } from '../redux/store'
import { Provider } from 'react-redux'
import { persistStore } from 'redux-persist'
import { PersistGate } from 'redux-persist/integration/react'
export default function App({ Component, pageProps }) {
const store = useStore(pageProps.initialReduxState)
const persistor = persistStore(store, {}, function () {
persistor.persist()
})
return (
<Provider store={store}>
<PersistGate loading={<div>loading</div>} persistor={persistor}>
<Component {...pageProps} />
</PersistGate>
</Provider>
)
}
All works fine inside the pages but when I try to use useDispatch or useSelector, I get the error. I am assuming it is because the _document is above the _app so it can wrap the template around it, but how can I make the store and dispatch available to the _document?
You should not add React components in _document - that should be done in _app instead.
From the Custom Document documentation:
Documentis only rendered in the server, event handlers likeonClickwon't work.- React components outside of
<Main />will not be initialized by the browser. Do not add application logic here or custom CSS (likestyled-jsx). If you need shared components in all your pages (like a menu or a toolbar), take a look at theAppcomponent instead.
The solution is to move PublicHeader and Footer to your custom _app, so they get initialised properly and have access to the Redux store.
export default function App({ Component, pageProps }) {
// Remaining code
return (
<Provider store={store}>
<PersistGate loading={<div>loading</div>} persistor={persistor}>
<PublicHeader />
<Component {...pageProps} />
<Footer />
</PersistGate>
</Provider>
)
}
When using workspaces make sure to have both @reduxjs/toolkit and react-redux installed in the workspace root node_modules folder.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With