This Is what I have done - which is something I came up with from the docs.
routes.cfg.js
First setup the routes config in a way that can be used for the client-side app and exported to used on the server too.
export const getRoutesConfig = () => [
{
name: 'homepage',
exact: true,
path: '/',
component: Dasboard
},
{
name: 'game',
path: '/game/',
component: Game
}
];
...
// loop through config to create <Routes>
Server
Setup the server routes to consume the config above and inspect components that have a property called needs (call this what you like, maybe ssrData or whatever).
// function to setup getting data based on routes + url being hit
async function getRouteData(routesArray, url, dispatch) {
const needs = [];
routesArray
.filter((route) => route.component.needs)
.forEach((route) => {
const match = matchPath(url, { path: route.path, exact: true, strict: false });
if (match) {
route.component.needs.forEach((need) => {
const result = need(match.params);
needs.push(dispatch(result));
});
}
});
return Promise.all(needs);
}
....
// call above function from within server using req / ctx object
const store = configureStore();
const routesArray = getRoutesConfig();
await getRouteData(routesArray, ctx.request.url, store.dispatch);
const initialState = store.getState();
container.js/component.jsx
Setup the data fetching for the component. Ensure you add the needs array as a property.
import { connect } from 'react-redux';
import Dashboard from '../../components/Dashboard/Dashboard';
import { fetchCreditReport } from '../../actions';
function mapStateToProps(state) {
return { ...state.creditReport };
}
const WrappedComponent = connect(
mapStateToProps,
{ fetchCreditReport }
)(Dashboard);
WrappedComponent.needs = [fetchCreditReport];
export default WrappedComponent;
Just a note, this method works for components hooked into a matching routes, not nested components. But for me this has always been fine. The component at route level does the data fetch, then the components that need it later either has it passed to them or you add a connector to get the data direct from the store.