Last active
July 22, 2017 09:15
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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