Closed fpoirier1 closed 6 years ago
I am just dashing out the door, but potentially this might help you: https://github.com/FormidableLabs/redux-little-router/issues/184#issuecomment-322487785
Or maybe this. Sorry it's got some of my own business logic in there.
// Middleware to trigger async actions based on the route that is currently being loaded.
export const routeFetch = store => next => action => {
if (action.type === LOCATION_CHANGED) {
// Always make sure vocabs are loaded
store.dispatch(fetchVocabs());
if (
action.payload
&& action.payload.params
&& action.payload.params.id
) {
switch(action.payload.route) {
case '/canonical/:id':
store.dispatch(fetchCanonical(
ModelUtils.buildHref('canonical', action.payload.params.id)
));
break;
case '/batch/:id':
store.dispatch(fetchBatch(
ModelUtils.buildHref('batch', action.payload.params.id)
));
break;
case '/unit/:id':
store.dispatch(fetchUnit(
ModelUtils.buildHref('unit', action.payload.params.id)
));
break;
case '/qc/:id':
store.dispatch(fetchQc(
ModelUtils.buildHref('qc', action.payload.params.id)
));
break;
}
} else if (
action.payload
&& action.payload.route === '/search'
&& action.payload.query.q
) {
store.dispatch(fetchSearchResults(action.payload.query.q));
}
}
return next(action);
};
And obviously if the state has not yet loaded, you have to handle that at the React component level. Usually I am preloading everything that could be the users "next" click so that they never have to wait on async for the next page to load. Combine that approach with server side rendering for when they hit a route directly and you have a nice user experience.
Thanks for your reply, it is really appreciated. Do you only use the middleware logic to fetch data ? Would it be a good place to do something like this ?
...
case '/unit/:id':
store.dispatch(selectUnit(action.payload.params.id))
break;
...
// actions.js
export const selectUnit = (id) =>{
return (dispatch) => {
dispatch(fetchUnit(
ModelUtils.buildHref('unit', id)
));
dispatch({type: SELECTED_UNIT, id});
}
}
If I understand this correctly your action-creator dispatches multiple actions, this is usually fine.
e.g. The one I reference from the unit part of the middleware looks like this.
export const fetchUnit = href => (dispatch, getState) => {
if (isFetchingHref(href)(getState())) {
return Promise.resolve();
}
dispatch(request(href));
return api.fetch.unit(href)
.then(data => {
dispatch(receiveObjs(href, mergeObjMaps(data)));
return data;
})
.catch(handle404(dispatch)(href));
};
I guess that answer my question. Thank you so much for your help. I will provided an example of my custom middle soon maybe it will inspire other developers.
I am trying to wrap my head around this little-router. I can't seem to find any example of a custom middleware implementation that would handle the
LOCATION_CHANGED
action.Here is my use case :
LOCATION_CHANGED
actiondispatch(editTodo(id))
todo = getState().todos.find(...)
list 6.2dispatch({type:'TODO_SELECTED', todo})
6.3 fetch todo detailsfetch('/todo/123')
(using thunk) 6.4 On fetch, the action creatordispatch({'TODO_DETAILS_SUCCEED'})
<Fragment>
components renders accordingly to the state and the containers maps the state to the props.Does that logic make sens ? Is there a simpler way to avoid using a middleware ?
Using this methodology, most of the
dispatch
will come from the custom middleware and the containers will simply use thepush()
function right ?