injectable middlewares, with typed hook #3252
Replies: 4 comments 9 replies
-
I've now changed the API and management logic to much more closely resemble export const dynamicInstance = createDynamicMiddleware();
export const startAppMiddleware = dynamicInstance.startMiddleware as TypedStartMiddleware<
RootState,
AppDispatch
>;
export const stopAppMiddleware = dynamicInstance.stopMiddleware as TypedStopMiddleware<
RootState,
AppDispatch
>;
export const addAppMiddleware = addMiddleware as TypedAddMiddleware<
RootState,
AppDispatch
>;
export const removeAppMiddleware = removeMiddleware as TypedRemoveMiddleware<
RootState,
AppDispatch
>;
export default dynamicInstance.middleware; the main challenge is to try and get a version of dispatch that knows about any injected middlewares, which is why i thought it could be useful if dispatching addMiddleware returned a pre-typed dispatch wrapper (with an attached method to remove the injected middleware) const mwAwareDispatch = dispatch(addMiddleware(middleware1, middleware2));
mwAwareDispatch(action(payload));
mwAwareDispatch.remove(); the hook would still be preferable in the context of a component of course, but that's not always available (and i'm not 100% sold on the logic inside that hook yet) const dispatch = useMiddlewareDispatch(middleware1, middleware2); using the map entry style from createListenerMiddleware, it's no longer a concern if the same middleware is injected twice - if it's the same function reference it'll use the same entry. |
Beta Was this translation helpful? Give feedback.
-
Some ideas.
export const addAppMiddleware = addMiddleware.withTypes<RootState, AppDispatch>();
// or, for consistency:
export const addAppMiddleware = addMiddleware.withTypes<{ state: RootState, dispatch: AppDispatch}>();
// in another file
export const useDispatchWithExtraMw = dispatchHookWithMiddleware(middleware1, middleware2)
//in the component
const dispatch = useDispatchWithExtraMw (); That would keep the middleware itself out of the component file, and we could already inject when |
Beta Was this translation helpful? Give feedback.
-
I've opened #3256 for a proper place to store the lib code, and updated the CSB to include some actual (if contrived) example of lazy loading components/middleware. :) |
Beta Was this translation helpful? Give feedback.
-
wonder if it's worth scoping the withMiddleware action to the instance (with an ID or something) - it might be desireable to have multiple dynamicMiddleware instances (e.g. one before all static middlewares, and one after) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
playing around with some ideas based on redux-dynamic-middlewares and createListenerMiddleware
typically the issue with injectable middlewares is that the dispatch typing is unaware of them, so i thought a custom
useDispatch
-style hook returning a dispatch that's aware of the middlewares it's injected could be usefulcodesandbox here
so far i've just reused redux-dynamic-middlewares' logic for managing injected middleware - there's nothing to prevent the same middleware being injected twice, etc. i did however change it so that you dispatch an action to add middleware, instead of exporting methods on an instance (as i wasn't entirely keen on the fact that
createDynamicMiddlewares
assumes you'll use the instance with only one store)edit:
i've now adapted it to use the same logic createListenerMiddleware uses to manage its listeners - each middleware entry has a map of MiddlewareAPI to the applied version of that middleware, to avoid doing it every dispatch
Beta Was this translation helpful? Give feedback.
All reactions