Search code examples
reduxreact-reduxredux-toolkitredux-middleware

How to use enhance store within redux middleware?


I am building a React-Redux application and need a middleware function that has access to an enhanced store. I am unable to get the enhanced store to be available in the middleware function. Is this possible, if so how?

https://codesandbox.io/s/redux-enhanced-store-in-middleware-e1c5uv?file=/src/main.ts

import {createElement} from 'react'
import {Provider, useDispatch} from 'react-redux'
import {configureStore, getDefaultMiddleware} from '@reduxjs/toolkit'
import { createRoot } from 'react-dom/client'

function reducer(state, action){
  console.debug("reducer...")
  return state
}

const apiMiddleware = (store) => (next) => (action) => {
  console.debug("apiMiddleware", store) // I would like store.api here
  return next(action)
}

const storeEnhancer = (next) => {
    const api = {doSomething: () => console.debug("api.doSomething")}
    
    return (reducer, initialState) => {
      const the_store = {api, ...next(reducer, initialState)}
      console.debug("storeEnhancer", the_store)
      return the_store
    }
  }

const store: any = configureStore({
  reducer,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(apiMiddleware),
  enhancers: (defaultEnhancers) => [...defaultEnhancers, storeEnhancer],
})

const ClickButton = () => {
  const dispatch = useDispatch()
  const onClick = () => dispatch({type: "action"})
  return createElement("button", {onClick}, "clicky")
}

export const app = () => 
{
  const rootElement = document.getElementById("root") 
  const root = createRoot(rootElement!) 
  root.render(createElement(Provider, {store, children: createElement(ClickButton)}))
  return createElement("div", {}, "hello")
}

Solution

  • Middleware don't get the entire Redux store as their outermost argument. Instead, they get a partial version - just {dispatch, getState}.

    This is why I prefer to refer to that variable as storeApi, rather than store, because it isn't the entire store:

    So yeah, if your enhancer is attaching extra fields to the store instance, you can't access those in the middleware.