The problem
I'm developing an google chrome extension where i add buttons to the already existing 3rd party react app. All of the data that im accessing by UI workarounds are accessible in the Redux Store by DevTools. How can i make my script injected into the app read the store as well as the dispatched actions
Best attempt
I've created this piece of code to load the store, then state and inspect actions, but for some reason only works in devtools console. Does not work from content_scripts injection. It returns empty set.
To run the code paste it in console and type callMe(). Then do some action on an app with redux
const callMe = function () {
function compose(...funcs) {
if (funcs.length === 0) {
// infer the argument type so it is usable in inference down the line
return (arg) => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce(
(a, b) =>
(...args) =>
a(b(...args))
)
}
// Find the root element for React
const roots = Array.from(document.querySelectorAll("*[id]"))
.filter((el:any) => el?._reactRootContainer?._internalRoot?.current)
.map((reactRoot:any) => reactRoot._reactRootContainer._internalRoot.current);
// Traverse a dom element
const stores = new Set();
const traverse = (element) => {
let store =
element?.memoizedState?.element?.props?.store
|| element?.pendingProps?.store
|| element?.stateNode?.store;
if (store) {
stores.add(store);
}
if (element.child) {
traverse(element.child);
}
};
// const internalRoot = reactRoot._reactRootContainer._internalRoot.current;
// Traverse the root react element to find all Redux States in the app
console.log(roots);
roots.forEach(traverse);
console.log(stores);
// @ts-ignore
let aStore= [...stores][0];
const ourMiddleware = ({ dispatch, getState }) => next => (action) => {
const result = typeof action === 'function' ? action(dispatch, getState) : next(action);
console.log(result, action);
return result;
};
const oldDispatch = aStore.dispatch;
const oldStore = {
...aStore,
dispatch: oldDispatch
}
allegroStore.dispatch = compose(ourMiddleware(oldStore))(oldDispatch);
};