How to fix Uncaught TypeError: Cannot read properties of undefined (reading 'state')
Hello,
I am trying to use the webext-redux package and I came across an error which I have a hard time solving.
Basically, I followed the first 2 required steps from the README of the webext-redux repository.
- I have a service worker file,
background.js, where I use thewrapStorefunction to wrap my Redux store. The background script seems to be executing fine, with no errors:
background.js
import store from '../src/store/store.js';
import {wrapStore} from 'webext-redux';
console.log("BEFORE wrap.")
wrapStore(store);
console.log("AFTER wrap")
- I created a proxy store in the React app and passed it to the Provider:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
import {Provider} from 'react-redux';
import {Store} from 'webext-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
const proxyStore = new Store();
proxyStore.ready().then(() => {
root.render(
<React.StrictMode>
<Provider store={proxyStore}>
<App />
</Provider>
</React.StrictMode>
);
});
The problem occurs when I try to use a Redux selector in one of my components, to retrieve the value from the store. The store.js looks like this:
import { configureStore } from '@reduxjs/toolkit';
import reliabilityAnalysisSliceReducer from './reliabilityAnalysisSlice.js';
export default configureStore({
reducer: {
reliabilityAnalysis: reliabilityAnalysisSliceReducer
}
})
reliabilityAnalysisSlice.js
import axios from 'axios';
import { createSlice } from '@reduxjs/toolkit';
// Slice
export const reliabilityAnalysisSlice = createSlice({
name: "reliabilityAnalysis",
initialState: {
shouldShowReliabilityAnalysis: false
},
reducers: {
showReliabilityAnalysis: (state, _) => {
state.shouldShowReliabilityAnalysis = true;
},
hideReliabilityAnalysis: (state, _) => {
state.shouldShowReliabilityAnalysis = false;
}
}
})
// Actions
export const {
showReliabilityAnalysis,
hideReliabilityAnalysis
} = reliabilityAnalysisSlice.actions
// Reducer
export default reliabilityAnalysisSlice.reducer;
And I use the selector like this:
const shouldShowReliabilityAnalysis = useSelector(state => state.shouldShowReliabilityAnalysis);
Which throws the following error:

There are hardly any sources on the internet that could help me, so I would higlhy appreciate if someone could lend me a hand.
Is this this package still supported and funcitonal? Or am I doing something wrong? Any hints on how to debug?
What version of react-redux do you use? I'm getting this error on v8 and it does work on v7. Reading changelogs of react-redux I found that it uses new useSyncExternalStore from react 18. This package hasn't been updated for a while so it may not support this new functionality. In my case it complains about it: at useSyncExternalStore......
For now I would stay at v7 but still I hope it will be addressed and fixed
Debugging it I discovered that "this" is undefined only sometimes.
Edit: all calls with this stack trace are undefined:
and this is the good working stack

There's two things happening here:
webext-reduxhas itsStoretype written as a class, not as a closure the way the real Redux library does. So,store.getStateinwebext-reduxis actually a class method that relies onthis- React-Redux v8 passes
store.getStateas an argument touseSyncExternalStore, which will be called later as justgetState(). That means that there's nothisbinding applied to thegetStatecall.
This works fine with normal Redux, but because webext-redux uses a class instance that explodes.
Tbh it's almost an accident that this ever worked with React-Redux until now.
So the only solution for this is to drop redux to v7?
@plusminushalf : React-Redux, yeah. Also looks like there's an open PR here in this repo (#289), but it hasn't been merged.
@plusminushalf if you want to use V8 you can use a workaround to make it work.
One possible solution is described here https://github.com/reduxjs/react-redux/issues/1963 . Creating the store like this might fix the problem.
const store = new Store()
Object.assign(store, {
dispatch: store.dispatch.bind(store),
getState: store.getState.bind(store),
subscribe: store.subscribe.bind(store),
})
Another solution would be to use a modified version of webext-redux with the applied fix. This is what I did. (You can find my rough notes in how to do that over here: https://dermeck.github.io/use-modified-npm-package/ )
btw I was having issues with thunk not working in redux toolkit, and this seems to have resolved it.
export const createStoreProxy = (portName: string) => {
const store = new Store({ portName });
const { dispatch: originalDispatch } = store;
// Fix for unresolved bug in webext-redux: https://github.com/tshaddix/webext-redux/issues/286
Object.assign(store, {
dispatch: ((action: AnyAction) => {
if (typeof action === 'function') {
// @ts-ignore
return action(store.dispatch, store.getState);
}
return originalDispatch(action);
}),
getState: store.getState.bind(store),
subscribe: store.subscribe.bind(store)
});
return store;
};