In trying to export my React's Redux store
from index.tsx
to be used somewhere else outside of the React application, I was getting an Invariant Violation:
Target container is not a DOM element
error while running Jest tests (with Enzyme and Webpack) in the App
component (App.tsx
).
I found a solution to this error for my use case, which was using the same Redux store React is using outside of React.
The initial code that didn't work when testing React looked like this.
// index.tsx
import * as React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { applyMiddleware, compose, createStore } from "redux";
import App from "./components/App";
import { rootReducer } from "./store/reducers";
import { initialState } from "./store/state";
const middlewares = [];
export const store = createStore(
rootReducer,
initialState,
compose(applyMiddleware(...middlewares)),
);
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root"),
);
Separate the Redux store logic into a new file named store.ts
, then create a default export
(to be used by index.tsx
, i.e., the React application) and a non-default export with export const store
(to be used from non-React classes), as follows.
// store.ts
import { applyMiddleware, compose, createStore } from "redux";
import logger from "redux-logger";
import { rootReducer } from "./store/reducers";
import { initialState } from "./store/state";
const middlewares = [];
export const store = createStore(
rootReducer,
initialState,
compose(applyMiddleware(...middlewares)),
);
export default store;
// updated index.tsx
import * as React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import store from "./store";
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root"),
);
// MyClass.ts
import { store } from "./store"; // store.ts
export default class MyClass {
handleClick() {
store.dispatch({ ...new SomeAction() });
}
}
default
exportA small note before you go. Here is how to use the default
and the non-default exports.
default export store;
is used with import store from "./store";
export const store = ...
is used with import { store } from "./store";
If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.