1

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")
}
slaughter98
  • 1,759
  • 14
  • 20
  • 1
    What’s an “enhanced store”? The relevant code should be part of the question. – Dave Newton Jan 23 '23 at 23:10
  • https://redux-toolkit.js.org/api/configureStore#enhancers – slaughter98 Jan 23 '23 at 23:18
  • Interesting question but I suspect that it's not possible, as the enhancers are the outermost layer. – Linda Paiste Jan 23 '23 at 23:52
  • I just figured out why the "api" doesn't show up, it is because the `applyMiddleware` strips the store down: https://github.com/reduxjs/redux/blob/9d4f0d8c8a66c3d255eeff6da8f7a93f74b8498a/src/applyMiddleware.ts#L76 – slaughter98 Jan 23 '23 at 23:55

1 Answers1

1

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.

markerikson
  • 63,178
  • 10
  • 141
  • 157