Dynamic imports in React - reactjs

I am trying to import dynamic of a file by means of process.env.NODE_ENV to import a style sheet or another one in production or in development. I have made a condition to load it but it gives me an error Error in ./src/index.js
Syntax error: 'import' and 'export' may only appear at the top level (13: 4) I guess this is not correct but ... how can I do it? I use create-react-app
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './components/App';
import routes from './routes';
import configureStore from './store/configureStore';
import initialState from './reducers/initialState';
if (process.env.NODE_ENV === 'production') {
import './styles/index.css';
}else {
import './styles/index.scss';
}
const store = configureStore(initialState);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Thanks!!!

As Laoujin mentions in the comments, you'll want to use require in this scenario.
For example, here's how I configure access to my Redux store, based on NODE_ENV, which could be adjusted to suit your needs:
const INITIAL_STATE = {};
function getStore () {
const configureStore = process.env.NODE_ENV === 'production'
? require('./configure-store.prod').default
: require('./configure-store.dev').default;
return configureStore(INITIAL_STATE);
}
export default getStore();

Related

How can i solve Module not found: Error: Can't resolve './reducers' while setting rootReducer in redux

I am trying to configure redux with my react app. While configuring rootReducer I am facing this error:
Module not found: Error: Can't resolve './reducers'
Here is my code:
import React from 'react';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import rootReducer from './reducers';
import { configureStore } from '#reduxjs/toolkit';
const store = configureStore({ reducer: rootReducer })
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Here is my folder structure and files screenshot
https://ibb.co/ZVbLh9S
What am I missing?
Thanks in Advance.
It seems like there is no file called reducers.js. But you have a usersSlice.js - are you taking things from multiple different tutorials here? In that case, please follow only one, from start to end, preferrably the official tutorial.
As for your problems - assuming this is your store.js and your userSlice.js contains export default slice.reducer, do the following:
import usersReducer from './usersSlice';
// ....
const store = configureStore({
reducer: {
users: usersReducer
}
})

Cant resolve './features/reducers' when trying to import rootreducer Redux

Here is my index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { App } from './App';
import { createStore } from 'redux'
import rootReducer from './features/reducers'
import { Provider } from 'react-redux';
import * as serviceWorker from './serviceWorker';
const store = createStore(rootReducer)
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
But i get the error in the title when i have it like this. here is the folder structure
BoxReducer.js file contains the following code.
import { boxConstants } from '../constants/BoxConstants';
export function boxes(state = {}, action) {
switch (action.type) {
case boxConstants.GET_BOXES_SUCCESS:
return {
items: action.boxes
};
case boxConstants.GET_BOXES_FAILURE:
return {
error: action.error
};
default:
return state
}
}
Might be here i do something wrong. i just have a hard time to understand were the rootreducer comes from. From what i read it comes from Redux itself and is not something i need to create
According to the folder structure features/reducers has a file named BoxReducer.js. Please try: import rootReducer from './features/reducers/BoxReducer.js'.
or if you want to keep
import rootReducer from './features/reducers' then please rename the file BoxReducer.js to index.js
If this also doesn't work then look into the BoxReducer.js file. If rootReducer module is not exported by default then add curly brackets around rootReducer, like {rootReducer} while importing.
You can try these ways. Thank you.
You need to specify the BoxReducer.js also in the import.
import rootReducer from './features/reducers/BoxReducer.js';

How to handle two configureStore files for Redux in TypeScript (multiple module.exports)?

I'm building a React Native app with TypeScript using Redux for my state.
I like using two seperate files for configureStore. In JS This looks like this:
configureStore.dev.js:
import { applyMiddleware, createStore } from "redux";
import logger from "redux-logger";
import reducers from "../reducers";
const configureStore = () => {
const store = createStore(reducers, applyMiddleware(logger));
return store;
};
export default configureStore;
configureStore.prod.js:
import { createStore } from "redux";
import reducers from "../reducers";
const configureStore = () => {
const store = createStore(reducers);
return store;
};
export default configureStore;
configureStore.js:
import Config from "react-native-config";
if (Config.REACT_ENVIRONMENT === "staging") {
module.exports = require("./configureStore.dev");
} else {
// tslint:disable-next-line no-var-requires
module.exports = require("./configureStore.prod");
}
And then within App.js:
import React, { Component } from "react";
import Orientation from "react-native-orientation";
import { Provider } from "react-redux";
import Navigator from "./navigation/Navigator";
import configureStore from "./redux/store/configureStore";
export const store = configureStore();
export default class App extends Component {
componentDidMount = () => {
Orientation.lockToPortrait();
};
render() {
return (
<Provider store={store}>
<Navigator />;
</Provider>
);
}
}
The problem now with TypeScript is that - after converting these files to .ts and .tsx - this code throws linting errors (and it furthermore blocks all Jest unit tests from running).
The lines where modules.exports exports the respective file depending on environment variables throws the error:
[tslint] require statement not part of an import statement (no-var-requires)
And in App.tsx the import of configureStore throws:
[ts] Module '"/Users/jan/Documents/FullStackFounders/PainButton/painbutton/app/redux/store/configureStore"' has no default export.
How would one handle this case in TypeScript?
The only solution I could come up with was only using one file and using a lot of if's for all the Dev only configs. But that doesn't seem clean to me.
It seems you are mixing import / export and require / module.exports syntax.
Try to use dynamic import expressions.
configureStore.js
export default Config.REACT_ENVIRONMENT === "staging" ? import("./configureStore.dev") : import("./configureStore.prod");
main render file
import configure from "./configureStore.js";
configure.then(configFunc => {
const store = configFunc();
ReactDOM.render(<App store={store} />, document.querySelector("#root"));
})
Pass the store as a prop to the <App /> Component.
I hope it will help.

#withRouter Unexpected Token Error

Seems every time I have to setup React Router in a new project I run into something new possibly by version changes.
I am using reactjs and mobx state tree(though at this point have not used anything of it).
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import HomeComponent from './HomeComponent.js';
import {withRouter, Route} from 'react-router'
#withRouter
export default class App extends Component {
render() {
return (
<Route exact path='/' component={HomeComponent}/>
);
}
}
export default App;
When I run it I get
ERROR in ./src/components/App.js
Module build failed: SyntaxError /components/App.js: Unexpected token (6:0)
I also get some warning as well
Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning.
Edit
Per the comment from "Artem Mirchenko"
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'mobx-react';
import { useStrict } from 'mobx';
import createBrowserHistory from 'history/createBrowserHistory';
import {syncHistoryWithStore } from 'mobx-react-router';
import { Router } from 'react-router'
import AppContainer from './components/App';
const browserHistory = createBrowserHistory();
import stores from '../src/stores/Stores';
const history = syncHistoryWithStore(browserHistory, stores.routingStore);
ReactDOM.render(
<Provider {... stores}>
<Router history={history}>
<AppContainer />
</Router>
</Provider>,
document.getElementById('app')
);
import {RouterStore} from 'mobx-react-router';
const routingStore = new RouterStore();
const stores = {
routingStore
}
export default stores;
You need to install babel plugin transform-decorators-legacy.
Via yarn:
yard add --dev transform-decorators-legacy
Vie npm:
npm install --save-dev transform-decorators-legacy
And add in to plugins ket in you babel options:
{
// pressets ....
"plugins": ["transform-decorators-legacy"]
}

Redux Hot Reload Warning on changes

I get the following warning when I try to update any of my react components...
Provider does not support changing store on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions.
As far as I can tell, my code looks like the instructions, but I still get the warning.
client.js
'use strict'
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { Router, browserHistory } from 'react-router';
import createStore from '../shared/store/createStore';
import routes from '../shared/routes';
const store = createStore(window.__app_data);
const history = browserHistory;
if (window.__isProduction === false) {
window.React = React; // Enable debugger
}
if (module.hot) {
module.hot.accept();
}
render (
<Provider store={store}>
<Router history={history} routes={routes} />
</Provider>,
document.getElementById('content')
)
configureStore.js
'use strict';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducers from '../reducers';
import { selectSubreddit, fetchPosts } from '../actions'
export default function createReduxStore(initialState = {}) {
const store = createStore(reducers, initialState, applyMiddleware(thunk));
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('../reducers', () => {
const nextReducer = require('../reducers').default;
store.replaceReducer(nextReducer);
});
}
return store;
};
Server.js
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import webpackConfig from '../../webpack.config.dev';
let compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler, {
hot: true,
noInfo: true,
publicPath: webpackConfig.output.publicPath
}));
app.use(webpackHotMiddleware(compiler));
Is there something I'm missing? Here is a link to the full Github Repo if you want to see the full src.
[Edited] Added server.js and github link.
Found the answer. There were multiple changes needed.
Remove module.hot code from client.js (Hot reloading that file caused Redux and React-Router warnings.
Create an index file for my React page components to export from.
Add module.hot code to newly created index file.
Change all React components to classes. const Page = () => () doesn't re-render with hot reloading.
After making those changes, everything started to work properly and I get no more warnings :-)

Resources