Skip to content

Instantly share code, notes, and snippets.

@faceyspacey
Last active July 22, 2017 09:15
Show Gist options
  • Select an option

  • Save faceyspacey/ce9fb6efd97eaa6cc09d6113c9aa03c8 to your computer and use it in GitHub Desktop.

Select an option

Save faceyspacey/ce9fb6efd97eaa6cc09d6113c9aa03c8 to your computer and use it in GitHub Desktop.
quick example of promise.all in Rudy route thunk to get data + module
// src/components/App.js
window.ASYNC_COMPONENTS = {}
const App = () => ...
export default App
// src/routesMap.js
const routesMap = {
ACTION_TYPE1: {
path: '/foo/:param1/:param2',
thunk: async (dispatch, getState) {
const someParams = getState().location.payload
const responses = await Promise.all([
import('./components/Foo'),
fetchData(someParams)
])
const component = responses[0].default
window.ASYNC_COMPONENTS['ACTION_TYPE1'] = component
const data = responses[1]
const action = { type: 'FETCH_DATA_ACTION_TYPE1', payload: data }
dispatch(action)
}
},
ACTION_TYPE2: ...
}
// src/components/MySplittingComponent.js
const MySplittingComponent ({ page }) => {
const Component = window.ASYNC_COMPONENTS[page] || Loading
return <Component />
}
export default connect(({ page }) => ({ page })(MySplittingComponent)
// src/reducers/page.js
import { NOT_FOUND } from 'redux-first-router'
export default (state = 'FETCH_DATA_ACTION_TYPE1', action = {}) =>
components[action.type] || state
const components = {
FETCH_DATA_ACTION_TYPE1: 'ActionType1',
FETCH_DATA_ACTION_TYPE2: 'ActionType2',
[NOT_FOUND]: 'Notfound'
}
// so this reducer is a variation of this reducer: https://github.com/faceyspacey/redux-first-router-demo/blob/master/src/reducers/index.js#L16
// it's tailored towards your Browserify environment. The basic idea is we use global state (`window.ASYNC_COMPONENTS`)
// to store any chunks/modules/components retreived from the server. Then in the thunk promise all, then first thing we do
// is put the module in that ASYNC_COMPONENTS hash object.
//
// Then after that we dispatch a non-Rudy action to tell the `page` reducer that the given page/component is ready.
// We follow the same pattern as we would would with react-universal-component + rudy, but instead of relying on
// the route type (e.g. ACTION_TYPE1), we create a new similar type, since in this case we have to indicate the page
// is ready at the end of the thunk, rather than the beginning.
//
// There's other ways to do it, but this is the general idea.
//
// You'll also likely want to do some caching for subsequent visits. In which case you can make the reducer smarter
// and let it navigate to the page on initial visitation of the route if you have the chunk (and possibly data) already.
//
// Lastly, what's missing which I'm sure u dont need help with is the reducer that responds to `FETCH_DATA_ACTION_TYPE2`
// and does something with the data. Basically it should store the response, and the same component rendered from
// the `page` reducer should use `connect` to get that data from the redux store.
//
// Here's what the component will look like:
// src/components/ActionType1
const ActionType1 = ({ data }) =>
data.rows.map(row => <div>{row.title}</div>)
export default connect(({ dataReducer }) => ({ data: dataReducer })(ActionType1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment