stormpath / stormpath-sdk-react

User Management and Authentication for React
Apache License 2.0
149 stars 57 forks source link

JSX routes only? #106

Open cparker15 opened 8 years ago

cparker15 commented 8 years ago

Will this SDK only support JSX routes? I'm trying to use async route definitions like this (from @davezuko's react-redux-starter-kit) with no success:

definition:

import CoreLayout from '../layouts/CoreLayout/CoreLayout'
import Home from './Home'

export const createRoutes = (store) => ({
  path: '/',
  component: CoreLayout,
  indexRoute: Home,
  getChildRoutes (location, cb) {
    require.ensure([], (require) => {
      cb(null, [
        // Provide store for async reducers and middleware
        require('./ChildRoute').default(store)
      ])
    })
  }
})

export default createRoutes

usage:

import React, { PropTypes } from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import createStore from './store/createStore'
import ReactStormpath, { Router } from 'react-stormpath'
import { useRouterHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
import createBrowserHistory from 'history/lib/createBrowserHistory'

const browserHistory = useRouterHistory(createBrowserHistory)({
  basename: __BASENAME__
})
const initialState = window.___INITIAL_STATE__
const store = createStore(initialState, browserHistory)
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState: (state) => state.router
})

const MOUNT_NODE = document.getElementById('root')

let render = (routerKey = null) => {
  const routes = require('routes').default(store)

  ReactStormpath.init({
    dispatcher: {
      type: 'redux',
      store
    }
  })

  ReactDOM.render(
    <AppContainer
      store={store}
      history={history}
      routes={routes}
      routerKey={routerKey}
    />,
    MOUNT_NODE
  )
}
render()

class AppContainer extends React.Component {
  static propTypes = {
    history: PropTypes.object.isRequired,
    routes: PropTypes.array.isRequired,
    routerKey: PropTypes.number,
    store: PropTypes.object.isRequired
  }

  render () {
    const { history, routes, routerKey, store } = this.props

    return (
      <Provider store={store}>
        <div style={{ height: '100%' }}>
          <Router history={history} children={routes} key={routerKey} />
        </div>
      </Provider>
    )
  }
}
typerandom commented 8 years ago

Thanks for reporting this issue. I'm going to look into it. I think the issue here is that the type property of the route is missing, and that is what we are looking at when we are mapping up the routes (see https://github.com/stormpath/stormpath-sdk-react/blob/master/src/components/Router.js#L59). In theory it should work if you add the property type and in that, specify the React-Stormpath router types (HomeRoute, AuthenticatedRoute and LoginRoute).

cparker15 commented 8 years ago

Thank you for your quick response! Unfortunately, adding the HomeRoute did not solve the issue.

However, I threw a try/catch around render() and caught this, which seems like it may be helpful.

Error: Objects are not valid as a React child (found: object with keys {type, path, component, indexRoute, getChildRoutes}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Router.

It seems that the routes prop is expected to be a JSX component exclusively, and it doesn't seem as though the childRoutes prop for PlainRoute objects is implemented. React Router's Router implementation supports passing PlainRoutes to both. https://github.com/reactjs/react-router/blob/master/docs/API.md#plainroute