gatsby: [v2] Cannot build for production when using Redux

Description

When I’m trying to build for production an error occurs: WebpackError: Invariant Violation: Could not find "store" in either the context or props of "Connect(FiltersPage)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(FiltersPage)".

Steps to reproduce

Component with connected Redux:

import { connect } from 'react-redux'
import { graphql } from 'gatsby'

import Layout from '../components/Layouts/filters'
import { arrayCombineUnique, extractNode, parseQueryFilters } from '../utils/helpers'
import { filtersActions } from '../components/Filters/state'
import ItemGroups from '../components/Items/ItemGroups'

class FiltersPage extends Component {
  componentDidMount () {
    const { setFilters, pageContext, data } = this.props

    const hotelsCategories = extractNode(data.allFirestoreHotel, 'categories')
    const allHotelsUniqueCategories = arrayCombineUnique(hotelsCategories)

    const toursCategories = extractNode(data.allFirestoreTour, 'categories')
    const allToursUniqueCategories = arrayCombineUnique(toursCategories)

    setFilters(parseQueryFilters(this.props.location.search))
    setFilters({ ...pageContext.filters, allHotelCategories: allHotelsUniqueCategories, allTourCategories: allToursUniqueCategories })
  }

  render () {
    const { data } = this.props

    return (
      <Layout>
        <ItemGroups data={data} />
      </Layout>
    )
  }
}

/**************************************************************
 * REDUX
 **************************************************************/

const mapDispatchTopProps = {
  setFilters: filtersActions.setFilters
}

export default connect(null, mapDispatchTopProps)(FiltersPage)

/**************************************************************
 * GRAPHQL
 **************************************************************/
export const pageQuery = graphql`
  query FiltersPage($country: String!) {
    allFirestoreTour(filter: { country: { eq: $country } }) {
      edges {
        node {
          id
          title
          country
          location
          region
          intro
          categories
          days
          collection
          coverImage
          fields {
            slug
            countrySlug
          }
        }
      }
    }
    allFirestoreTrip(filter: { country: { eq: $country } }) {
      edges {
        node {
          id
          title
          country
          location
          region
          intro
          collection
          coverImage
          fields {
            slug
            countrySlug
          }
        }
      }
    }
    allFirestoreHotel(filter: { country: { eq: $country } }) {
      edges {
        node {
          id
          title
          country
          location
          region
          intro
          categories
          coverImage
          stars
          collection
          fields {
            slug
            countrySlug
          }
        }
      }
    }
  }
`

Usual gatsby build command: node --max_old_space_size=8196 ./node_modules/.bin/gatsby build

Expected result

Compilation should be successful as it was in v1

Actual result

Full build log:

success onPreBootstrap — 0.133 s
success delete html and css files from previous builds — 6.535 s
success copy gatsby files — 0.013 s
⢀ source and transform nodes -> wordpress__POST fetched : 1
⡀ source and transform nodes -> wordpress__PAGE fetched : 6
⠁ source and transform nodes -> wordpress__wp_media fetched : 15
⠠ source and transform nodes -> wordpress__wp_blocks fetched : 0
⠄ source and transform nodes -> wordpress__wp_jp_pay_order fetched : 0
⠈ source and transform nodes -> wordpress__wp_jp_pay_product fetched : 0
⢀ source and transform nodes -> wordpress__wp_feedback fetched : 0
⠂ source and transform nodes -> wordpress__wp_types fetched : 1
⠐ source and transform nodes -> wordpress__wp_statuses fetched : 1
⡀ source and transform nodes -> wordpress__wp_taxonomies fetched : 1
⠁ source and transform nodes -> wordpress__CATEGORY fetched : 4
⠠ source and transform nodes -> wordpress__TAG fetched : 1
⠄ source and transform nodes -> wordpress__wp_users fetched : 3
⠈ source and transform nodes -> wordpress__wp_me fetched : 1
⢀ source and transform nodes -> wordpress__wp_comments fetched : 0
⠂ source and transform nodes -> wordpress__wp_settings fetched : 1
⠂ source and transform nodes -> wordpress__wp_credential fetched : 2
success source and transform nodes — 12.415 s
success building schema — 1.557 s
success createPages — 3.742 s
success createPagesStatefully — 0.193 s
success onPreExtractQueries — 0.001 s
success update schema — 1.071 s
warning There are conflicting field types in your data. GraphQL schema will omit those fields.
wordpress__wp_media.media_details.width:
 - type: number
   value: 4896
 - type: string
   value: '1600'
wordpress__wp_media.media_details.height:
 - type: number
   value: 2752
 - type: string
   value: '953'
firestoreTour.versions[].hotels[].hotelID:
 - type: number
   value: 0
 - type: string
   value: '204'
success extract queries from components — 0.806 s
success run graphql queries — 0.091 s
success write out page data — 0.090 s
success write out redirect data — 0.001 s
success onPostBootstrap — 0.001 s

info bootstrap finished - 29.594 s

success Building production JavaScript and CSS bundles — 101.468 s

error Building static HTML for pages failed

See our docs page on debugging HTML builds for help https://goo.gl/yL9lND

  38 |       var args = [a, b, c, d, e, f];
  39 |       var argIndex = 0;
> 40 |       error = new Error(
     | ^
  41 |         format.replace(/%s/g, function() { return args[argIndex++]; })
  42 |       );
  43 |       error.name = 'Invariant Violation';


  WebpackError: Invariant Violation: Could not find "store" in either the context or props of "Connect(FiltersPage)".   Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(FiltersPage)".
  
  - invariant.js:40 invariant
    [lib]/[invariant]/invariant.js:40:1
  
  - connectAdvanced.js:117 new Connect
    [lib]/[react-redux]/es/components/connectAdvanced.js:117:1
  
  - react-dom-server.node.production.min.js:26 d
    [lib]/[react-dom]/cjs/react-dom-server.node.production.min.js:26:314
  
  - react-dom-server.node.production.min.js:28 wa
    [lib]/[react-dom]/cjs/react-dom-server.node.production.min.js:28:493
  
  - react-dom-server.node.production.min.js:33 a../node_modules/react-dom/cjs/react-dom-server.node.production.min.js.    a.render
    [lib]/[react-dom]/cjs/react-dom-server.node.production.min.js:33:46
  
  - react-dom-server.node.production.min.js:32 a../node_modules/react-dom/cjs/react-dom-server.node.production.min.js.    a.read
    [lib]/[react-dom]/cjs/react-dom-server.node.production.min.js:32:246
  
  - react-dom-server.node.production.min.js:43 renderToString
    [lib]/[react-dom]/cjs/react-dom-server.node.production.min.js:43:1
  
  - static-entry.js:170 Object._default [as default]
    lib/.cache/static-entry.js:170:16
  
  - bootstrap:12 Worker.Queue [as fn]
    lib/webpack/bootstrap:12:1
  
  - bootstrap:58 Worker.start
    lib/webpack/bootstrap:58:1
  
  
  - gatsby-browser-entry.js:36 
    lib/.cache/gatsby-browser-entry.js:36:7
  
  - bootstrap:76 MemoryStore.getLock
    lib/webpack/bootstrap:76:1
  
  
  - bootstrap:58 MemoryStore.takeFirstN
    lib/webpack/bootstrap:58:1
  
  - find-page.js:27 Queue._getNextBatch
    lib/.cache/find-page.js:27:7

Environment

  System:
    OS: Linux 4.17 Solus 3.9999
    CPU: x64 Intel(R) Core(TM) i7-2820QM CPU @ 2.30GHz
    Shell: 4.4.19 - /bin/bash
  Binaries:
    Node: 8.11.3 - /usr/bin/node
    Yarn: 1.7.0 - /usr/bin/yarn
    npm: 5.6.0 - /usr/bin/npm
  Browsers:
    Firefox: 61.0
  npmPackages:
    gatsby: next => 2.0.0-beta.13 
    gatsby-cli: next => 2.0.0-beta.3 
    gatsby-paginate: next => 1.0.16 
    gatsby-plugin-less: next => 2.0.0-beta.3 
    gatsby-plugin-react-helmet: next => 3.0.0-beta.3 
    gatsby-source-firebase: next => 1.0.0 
    gatsby-source-firestore: next => 1.0.2 
    gatsby-source-wordpress: next => 3.0.0-beta.4 
  npmGlobalPackages:
    gatsby-cli: 1.1.58

File contents (if changed)

gatsby-browser.js:

import { Router } from 'react-router-dom'
import { Provider } from 'react-redux'
import firebase from 'firebase/app'

import createStore from './src/state/createStore'
import { loadState, saveState } from './src/state/localStorage'

const config = {
  apiKey: 'AIzaSyC4PU0ILY45uZ3oDe5Y4S-w6go1dRVHF4E',
  authDomain: 'tourasia-ch.firebaseapp.com',
  databaseURL: 'https://tourasia-ch.firebaseio.com',
  projectId: 'tourasia-ch',
  storageBucket: 'tourasia-ch.appspot.com',
  messagingSenderId: '712966527886'
}
firebase.initializeApp(config)

const persistedState = loadState()

export const replaceRouterComponent = ({ history }) => {
  const store = createStore(persistedState)

  store.subscribe(() => {
    saveState({
      wishlist: store.getState().wishlist
    })
  })

  const ConnectedRouterWrapper = ({ children }) => (
    <Provider store={store}>
      <Router history={history}>{children}</Router>
    </Provider>
  )

  return ConnectedRouterWrapper
}

gatsby-ssr.js:

import { Provider } from 'react-redux'
import { renderToString } from 'react-dom/server'

import createStore from './src/state/createStore'

exports.replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
  const store = createStore()

  const ConnectedBody = () => (
    <Provider store={store}>
      {bodyComponent}
    </Provider>
  )
  replaceBodyHTMLString(renderToString(<ConnectedBody />))
}

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 16 (3 by maintainers)

Most upvoted comments

In my situation im forced to use both gatsby-browser and gatsby-ssr, if i do not use gatsby-ssr` develop will work without issue but build WILL NOT.

gatsby-ssr is required for build regardless if you plan to support SSR

https://github.com/gatsbyjs/gatsby/tree/master/examples/using-redux

@m-allanson as he mentioned above, replace exports.replaceRenderer with export const replaceRenderer both gatsby-browser.js and gatsby-ssr.js

I got an issue like this. I don’t know if it’s the same as this one, but the fix was weird…

This is how my gatsby-ssr.js looked like:

export function wrapRootElement({ element }) {
  const initialState = calculateInitialState();
  const store = configureStore(initialState);
  return (
    <App store={store}>{element}</App>
  );
}

The problem appeared to be with that fact that I did export function rather than export const.

By doing this instead, it worked:

export const wrapRootElement = ({ element }) => {
  const initialState = calculateInitialState();
  const store = configureStore(initialState);
  return (
    <App store={store}>{element}</App>
  );
};

I don’t get it why export function doesn’t work, even though it worked fine to use export function in gatsby-browser.js.

I wonder if this might relate to #13667; though I didn’t use CommonJS syntax, just export function instead of export const.

Does it work if you replace exports.replaceRenderer with export const replaceRenderer? If so, Gatsby should provide more helpful errors for this as part of the fix for #4718.

Edit: see also https://next.gatsbyjs.org/docs/migrating-from-v1-to-v2/#convert-to-either-pure-commonjs-or-pure-es6

I was able to add Redux to my Gatsby-v2 application with attaching the provider to my layout component, and connect to my header component, However when adding connect to a page component, i received the same error.

A quick work around is to have a custom connect component:

import React from 'react'
import { connect } from "react-redux";
import store from '../redux/store'

const connectWithStore = (mapStateToProps = null, mapDispatchToProps = null, mergeProps = null) => WrappedComponent =>{
    const ConnectedWrappedComponent = connect(mapStateToProps,mapDispatchToProps,mergeProps)(WrappedComponent)
  return props => <ConnectedWrappedComponent {...props} store={store} />
}

export default connectWithStore

Usage: export default connectWithStore(mapStateToProps,mapDispatchToProps)(index)

https://github.com/reduxjs/react-redux/issues/390