Search code examples
javascriptreactjsreduxreact-engine

Access server props from within redux?


I'm trying to use redux, react-engine, and react-router.

The issue or question I have is that react-engine provides an object of props that come from the server. How do I access these props from within my ProvidedApp?

ProvidedApp.js

import React from 'react'
import { connect, Provider } from 'react-redux'
import App from './app'
import { mapStateToProps, mapDispatchToProps, store } from './redux-stuff'

// Connected Component
let ConnectedApp = connect(
  mapStateToProps,
  mapDispatchToProps
)(App)

let ProvidedApp = () => (
  <Provider store={store}>
    <ConnectedApp/>
  </Provider>
)

export default ProvidedApp

Routes.js

import React from 'react'
import { Router, Route } from 'react-router'

import Layout from './views/Layout'
import App from './views/ProvidedApp'

module.exports = (
  <Router>
    <Route path='/' component={Layout}>
      <Route path='/app' component={App} />
      <Route path='/app/dev' component={App} />
    </Route>
  </Router>
)

I also think my configuration is a little wonky, I couldn't get Provider working any other way. If theres a way to have Provider wrap the Router I'd love to get that working.


Here's some code of what it looks like when I move Provider above Router

ConnectedApp.js

import React from 'react'
import { connect, Provider } from 'react-redux'
import App from './app'
import { mapStateToProps, mapDispatchToProps} from './redux-stuff'

let ConnectedApp = connect(
  mapStateToProps,
  mapDispatchToProps
)(App)

export default ConnectedApp

Routes.js

import React from 'react'
import { Provider } from 'react-redux'
import { Router, Route } from 'react-router'
import { store } from './redux-stuff'

import Layout from './views/Layout'
import App from './views/ConnectedApp'

module.exports = (
  <Provider store={store}>
    <Router>
      <Route path='/' component={Layout}>
        <Route path='/app' component={App} />
      </Route>
    </Router>
  </Provider>
)

I get this error:

Could not find "store" in either the context or props of "Connect(App)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(App)".


Update

I found that I can access from he code in my first example within ProvidedApp. But I have no clue how I'm supposed to pass it into Redux.

let ProvidedApp = (props) => {
  console.log(props)
  return (
    <Provider store={store}>
      <ConnectedApp/>
    </Provider>
  )
}

Solution

  • Seems like I need to wrap the reducer and store and pass in the ServerProps to the default state like this.

    let getDefaultState = (serverProps) => {
      return {
        'appName': serverProps.appName 
      }
    }
    
    let getReducer = (serverProps) => {
      let defaultState = getDefaultState(serverProps)
      return (state = defaultState, action) => {
    
      }
    }
    
    let getStore = (serverProps) => {
      let reducer = getReducer(serverProps)
      return store = createStore(reducer)
    }
    
    let ConnectedApp = connect(
      mapStateToProps,
      mapDispatchToProps
    )(App)
    
    let ProvidedApp = (serverProps) => {
      return (
        <Provider store={getStore(serverProps)}>
          <ConnectedApp/>
        </Provider>
      )
    }
    

    This is super ugly :/