How to use rtl layout of material-ui next in react app - reactjs

I want to use rtl layout in my react application. I have used material-ui next version to integrate this application. I have used below code to make application layout rtl. Some components work properly in the rtl layout but some components doesn't affected.
/**
* App.js Layout Start Here
*/
import React, { Component } from 'react';
import { connect } from 'react-redux';
import classnames from 'classnames';
import { MuiThemeProvider } from 'material-ui/styles';
import { IntersectingCirclesSpinner } from 'react-epic-spinners';
import { IntlProvider } from 'react-intl';
import { Redirect, Route } from 'react-router-dom';
import { NotificationContainer } from 'react-notifications';
// app routes
import Dashboard from '../routes/dashboard';
import AppSignUp from '../routes/AppSignUp';
// App locale
import AppLocale from '../lang';
// themes
import lightTheme from './themes/lightTheme';
import darkTheme from './themes/darkTheme';
class App extends Component {
state = {
loading: true
}
componentDidMount() {
let self = this;
setTimeout(() => {
self.setState({ loading: false });
}, 1000);
}
render() {
const { locale, darkMode, rtlLayout } = this.props.settings;
if (this.state.loading) {
return (
<div className="d-flex justify-content-center">
<IntersectingCirclesSpinner color="red" className="rct-loader" />
</div>
);
}
const currentAppLocale = AppLocale[locale.locale];
let theme = '';
if (darkMode) {
theme = darkTheme
} else {
theme = lightTheme
}
if (rtlLayout) {
theme.direction = 'rtl'
} else {
theme.direction = 'ltr'
}
return (
<MuiThemeProvider theme={theme}>
<IntlProvider
locale={currentAppLocale.locale}
messages={currentAppLocale.messages}
>
<React.Fragment>
<NotificationContainer />
<Route path="/dashboard" component={Dashboard} />
<Route path="/signup" component={AppSignUp} />
</React.Fragment>
</IntlProvider>
</MuiThemeProvider>
);
}
}
// map state to props
const mapStateToProps = ({ settings, authUser }) => {
const { user } = authUser;
return { settings, user };
};
export default connect(mapStateToProps)(App);
It doesn't work properly also i have added
<html dir="rtl">...</html>

(1) Don't mutate the theme directly, use getMuiTheme instead:
themeWithDirection = getMuiTheme(theme, { direction: 'rtl' });
Based on: https://github.com/mui-org/material-ui/issues/1926#issuecomment-192736335
(2) Create the RTL component as shown in the Material-UI documentation and put it around your root component:
function RTL(props) {
return (
<JssProvider jss={jss} generateClassName={generateClassName}>
{props.children}
</JssProvider>
);
}
return (
<RTL>
<MuiThemeProvider theme={themeWithDirection}>
{/* your component code */}
</MuiThemeProvider>
</RTL>
);
Props to this answer for explicitly showing what to do with the RTL function.

Related

Hiding Banner at a certain page

I'm currently attempting to hide the banner at a certain page. I have successfully hid the banner in all other pages except one with a page with a id. I have a dynamic folder named [content]
import { useRouter } from "next/router";
const HIDDEN_BOARDLIST = ["/board/board_list"];
//this is successful
const HIDDEN_BOARDDETAILS = [`board/${content}`].
//this does not work
//http://localhost:3000/board/620471f057aad9002de7f04f. I have to enter the id manually but since this is a dynamic, the id will change every time
export default function Layout(props: ILayoutProps) {
const router = useRouter();
console.log(router.asPath);
const isHiddenBoardList = HIDDEN_BOARDLIST.includes(router.asPath);
return (
<Wrapper>
<Header />
{!isHiddenBoardList && <Banner />}
<BodyWrapper>
<Body>{props.children}</Body>
</BodyWrapper>
</Wrapper>
);
}
useRouter is a hook.
CSR
import React, { useState, useEffect } from 'React';
import { useRouter } from "next/router";
interface ILayoutProps {
//...
}
export default function Layout(props: ILayoutProps) {
const router = useRouter();
const [hidden, setHidden] = useState(false);
useEffect(() => {
if(router.asPath.includes('board/')) {
setHidden(true);
}
}, [router.asPath]);
return (
<Wrapper>
<Header />
{!hidden && <Banner />}
<BodyWrapper>
<Body>{props.children}</Body>
</BodyWrapper>
</Wrapper>
);
}
Since this code is CSR, flickering may occur. <Banner /> will disappear after being rendered.
If you don't want that, there is a way to pass the current url as props of the <Layout /> component via getServerSideProps.
SSR
// pages/board/[id].tsx
import { GetServerSideProps, NextPage } from 'next';
import Head from 'next/head';
interface Props {
url: string;
}
const BoardPage: NextPage<Props> = (props: Props) => {
return (
<>
<Layout {...props} />
</>
);
};
export const getServerSideProps: GetServerSideProps = async (context) => {
const { resolvedUrl } = context; //ex) /board/12345?id=12345
return {
props: {
url: resolvedUrl ,
}, // will be passed to the page component as props
};
};
// components/Layout.tsx
import React, { useState, useEffect } from 'React';
import { useRouter } from "next/router";
interface ILayoutProps {
url: string;
// ...
}
export default function Layout(props: ILayoutProps) {
return (
<Wrapper>
<Header />
{props.url.includes('board/') && <Banner />}
<BodyWrapper>
<Body>{props.children}</Body>
</BodyWrapper>
</Wrapper>
);
}
I hope these two kinds of code are helpful.

Using React Context to Integrate Firebase Cause Infinite Loading When Import Component using Loadable

I'm trying to integrate Firebase to React using React Context. The React project uses the Able template. When I wrap my App component with ContextProvider, it causes an infinite loop.
Here is the code:
./Firebase/firebase.js
import React, { createContext } from "react";
import { useDispatch } from "react-redux";
import firebaseConfig from "./firebaseConfig";
import app from "firebase/app";
import 'firebase/auth';
import 'firebase/firestore';
import "firebase/database";
import { setLoggedUser } from '../store/actions'
// we create a React Context, for this to be accessible
// from a component later
const FirebaseContext = createContext(null);
export { FirebaseContext };
export default ({ children }) => {
let firebase = {
app: null,
database: null,
};
const dispatch = useDispatch();
// check if firebase app has been initialized previously
// if not, initialize with the config we saved earlier
if (!app.apps.length) {
app.initializeApp(firebaseConfig);
firebase = {
app: app,
database: app.database(),
api: {
getUserProfile,
},
};
}
// function to query logged user from the database and
// fire a Redux action to update the items in real-time
function getUserProfile() {
....
}
};
return <FirebaseContext.Provider value={firebase}>{children}</FirebaseContext.Provider>;
};
./index.js
import React from "react";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider } from "react-redux";
import { BrowserRouter } from "react-router-dom";
import App from "./App/index";
import * as serviceWorker from "./serviceWorker";
import reducer from "./store/reducer";
import config from "./config";
import "./assets/scss/style.scss";
import FirebaseProvider from './Firebase/firebase.js';
const store = createStore(reducer);
const app = (
<Provider store={store}>
<BrowserRouter basename={config.basename}>
<FirebaseProvider> <----- cause infinite loading
<App />
</FirebaseProvider>
</BrowserRouter>
</Provider>
);
ReactDOM.render(app, document.getElementById("root"));
The source code that causes the error is where the loadable import component AdminLayout in App/index.js
./App/index.js
import React, { Component, Suspense } from "react";
import { Switch, Route } from "react-router-dom";
import Loadable from "react-loadable";
import "../../node_modules/font-awesome/scss/font-awesome.scss";
import Loader from "./layout/Loader";
import Aux from "../hoc/_Aux";
import ScrollToTop from "./layout/ScrollToTop";
import routes from "../route";
import { FirebaseContext } from '../Firebase/firebase.js';
const AdminLayout = Loadable({
loader: () => {
debugger
return import("./layout/AdminLayout")}, // Cause Infinite Loading
loading: Loader,
});
const App = () => {
const { app, api } = React.useContext(FirebaseContext);
const menu = routes.map((route, index) => {
return route.component ? (
<Route
key={index}
path={route.path}
exact={route.exact}
name={route.name}
render={(props) => <route.component {...props} />}
/>
) : null;
});
return (
<Aux>
<ScrollToTop>
<Suspense fallback={<Loader />}>
<Switch>
{menu}
<Route path="/" component={AdminLayout} />
</Switch>
</Suspense>
</ScrollToTop>
</Aux>
);
}
export default App;
I lost in the debugging process when I try to know what's going on inside this AdminLayout component. This component is coming from the template.
./App/layout/AdminLayout/index.js
import React, { Component, Suspense } from "react";
import { Route, Switch, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import Fullscreen from "react-full-screen";
import windowSize from "react-window-size";
import Navigation from "./Navigation";
import NavBar from "./NavBar";
import Breadcrumb from "./Breadcrumb";
import Configuration from "./Configuration";
import Loader from "../Loader";
import routes from "../../../routes";
import Aux from "../../../hoc/_Aux";
import * as actionTypes from "../../../store/actions";
//import '../../../app.scss';
class AdminLayout extends Component {
fullScreenExitHandler = () => {
if (
!document.fullscreenElement &&
!document.webkitIsFullScreen &&
!document.mozFullScreen &&
!document.msFullscreenElement
) {
this.props.onFullScreenExit();
}
};
UNSAFE_componentWillMount() {
if (
this.props.windowWidth > 992 &&
this.props.windowWidth <= 1024 &&
this.props.layout !== "horizontal"
) {
this.props.onUNSAFE_componentWillMount();
}
}
mobileOutClickHandler() {
if (this.props.windowWidth < 992 && this.props.collapseMenu) {
this.props.onUNSAFE_componentWillMount();
}
}
render() {
/* full screen exit call */
document.addEventListener("fullscreenchange", this.fullScreenExitHandler);
document.addEventListener(
"webkitfullscreenchange",
this.fullScreenExitHandler
);
document.addEventListener(
"mozfullscreenchange",
this.fullScreenExitHandler
);
document.addEventListener("MSFullscreenChange", this.fullScreenExitHandler);
const menu = routes.map((route, index) => {
return route.component ? (
<Route
key={index}
path={route.path}
exact={route.exact}
name={route.name}
render={(props) => <route.component {...props} />}
/>
) : null;
});
let mainClass = ["pcoded-wrapper"];
if (
this.props.layout === "horizontal" &&
this.props.subLayout === "horizontal-2"
) {
mainClass = [...mainClass, "container"];
}
return (
<Aux>
<Fullscreen enabled={this.props.isFullScreen}>
<Navigation />
<NavBar />
<div
className="pcoded-main-container"
onClick={() => this.mobileOutClickHandler}
>
<div className={mainClass.join(" ")}>
<div className="pcoded-content">
<div className="pcoded-inner-content">
<Breadcrumb />
<div className="main-body">
<div className="page-wrapper">
<Suspense fallback={<Loader />}>
<Switch>
{menu}
<Redirect from="/" to={this.props.defaultPath} />
</Switch>
</Suspense>
</div>
</div>
</div>
</div>
</div>
</div>
<Configuration />
</Fullscreen>
</Aux>
);
}
}
const mapStateToProps = (state) => {
debugger
return {
defaultPath: state.defaultPath,
isFullScreen: state.isFullScreen,
collapseMenu: state.collapseMenu,
layout: state.layout,
subLayout: state.subLayout,
};
};
const mapDispatchToProps = (dispatch) => {
debugger
return {
onFullScreenExit: () => dispatch({ type: actionTypes.FULL_SCREEN_EXIT }),
onUNSAFE_componentWillMount: () =>
dispatch({ type: actionTypes.COLLAPSE_MENU }),
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(windowSize(AdminLayout));
Could anyone have an idea why this is happening or maybe how to debug to find the problem? Thank you.
EDIT: When I import the AdminLayout directly without using Loadable, it works fine. How to make this work using Loadable?

State is changing but colors are not changing

import React, { Component, useState } from "react";
import { createMuiTheme, MuiThemeProvider } from "#material-ui/core/styles";
import Switch from "#material-ui/core/Switch";
import LoginPage from "./Dashboard/Login";
class App extends Component {
state = { darkState: false };
render() {
const { darkState } = this.state;
return (
<MuiThemeProvider
theme={darkState ? this.props.darkTheme : this.props.theme}
>
<div className="App">
<Switch
checked={darkState}
onChange={() => this.setState({ darkState: !darkState })}
/>
<LoginPage />
</div>
</MuiThemeProvider>
);
}
}
export default App;
When it is clicked switch for the first time, the color changes but does not return again.
I see that when I look at the console log it works.
According to Material UI, theme props type is object or func
link document

React Router v4 and loadable-components always rendering same Component even though the route matches other

I've got a Standard React-Redux Application with react router v4, webpack 4 and I'm trying to perform lazy loading of components via loadable-components library, so webpack can create chunks and load them on demand. The problems seems it's always rendering the Dashboard (refer code below) Component inside the <Switch>, no matter the route.
I don't understand the cause. I found a similar problem: React-Router v4 rendering wrong component but matching correctly but it follows a different pattern and I can't or don't understand how to apply that solution into my issue.
I'm posting The main AppContainer and the routes file:
AppContainer.js:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Provider } from 'react-redux'
import ReduxToastr from 'react-redux-toastr'
import 'react-redux-toastr/src/styles/index.scss'
import { Offline, Online } from 'react-detect-offline'
import Footer from 'components/Footer/'
import { Modal, ModalHeader, ModalBody } from 'reactstrap'
import { Translate } from 'react-redux-i18n'
import { PersistGate } from 'redux-persist/integration/react'
import { Router, Switch, Route } from 'react-router-dom'
import PrivateRoute from 'components/PrivateRoute'
import { Dashboard, PasswordReset, PasswordResetEdit, SignIn } from 'routes'
// Layout
import CoreLayout from 'layouts/CoreLayout'
class AppContainer extends Component {
static propTypes = {
history: PropTypes.object.isRequired,
persistor: PropTypes.object.isRequired, // redux-persist
store : PropTypes.object.isRequired
}
render () {
const { history, store, persistor } = this.props
const opened = true
const toastrDefaultTimeout = 8000
const newToastrAlwaysOnTop = false
return (
<div>
<Online>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<div style={{ height: '100%' }}>
<ReduxToastr
timeOut={toastrDefaultTimeout}
newestOnTop={newToastrAlwaysOnTop}
preventDuplicates
position='top-right'
transitionIn='fadeIn'
transitionOut='fadeOut'
progressBar />
<Router history={history}>
<CoreLayout {...this.props} >
<Switch>
<Route exact path='/sign-in' component={SignIn} />
<Route exact path='/passwords/new' component={PasswordReset} />
<Route exact path='/passwords/edit' component={PasswordResetEdit} />
<PrivateRoute exact path='/' component={Dashboard} persistor={persistor} />
</Switch>
</CoreLayout>
</Router>
</div>
</PersistGate>
</Provider>
</Online>
<Offline>
<div className='app'>
<div className='app-body'>
<main className='main align-items-center align-self-center'>
<div className='container'>
<div className='animated fadeIn'>
<Modal isOpen={opened} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}><Translate value={`views.shared.no-internet.title`} /></ModalHeader>
<ModalBody>
<div className='card-block'>
<div className='row'>
<div className='col-sm-12'>
<Translate value='views.shared.no-internet.description' />
</div>
</div>
</div>
</ModalBody>
</Modal>
</div>
</div>
</main>
</div>
<Footer />
</div>
</Offline>
</div>
)
}
}
export default AppContainer
routes/index.js:
// We only need to import the modules necessary for initial render
import loadable from 'loadable-components'
import { hot } from 'react-hot-loader'
// Component split-code (lazy load)
let Dashboard,
SignIn,
PasswordReset,
PasswordResetEdit
// Needed for HMR
if (__DEV__) {
Dashboard = hot(module)(loadable(() => import('./Dashboard')))
PasswordReset = hot(module)(loadable(() => import('./PasswordReset')))
PasswordResetEdit = hot(module)(loadable(() => import('./PasswordResetEdit')))
SignIn = hot(module)(loadable(() => import('./SignIn')))
} else {
Dashboard = loadable(() => import('./Dashboard'))
SignIn = loadable(() => import('./SignIn'))
PasswordReset = loadable(() => import('./PasswordReset'))
PasswordResetEdit = loadable(() => import('./PasswordResetEdit'))
}
export { Dashboard, PasswordReset, PasswordResetEdit, SignIn }
And for anyone curious, here is the PrivateRoute component:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Route, Redirect } from 'react-router-dom'
import { connect } from 'react-redux'
import { validateSession } from 'modules/sessions/session'
const mapStateToProps = state => ({
session: state.session
})
const mapDispatchToProps = (dispatch) => {
return {
validateSession: () => { dispatch(validateSession()) }
}
}
class PrivateRoute extends Component {
componentDidMount () {
this.props.validateSession(this.props.persistor)
}
render () {
const { component: Component, session, ...rest } = this.props
return (
<Route {...rest} render={(routeProps) =>
this.props.session.userSignedIn ? <Component {...routeProps} />
: <Redirect to={{
pathname: '/sign-in',
state: { from: routeProps.location }
}} />
}
/>)
}
}
PrivateRoute.propTypes = {
component: PropTypes.func.isRequired,
persistor: PropTypes.object.isRequired,
session: PropTypes.object.isRequired,
validateSession: PropTypes.func.isRequired
}
export default connect(mapStateToProps, mapDispatchToProps)(PrivateRoute)
If I remove the if (_DEV_) block in routes/index.js and always do it like the 'else' block everything works okay, however I lose HMR, meaning I have to refresh the browser to see code changes take effect.
Edit
For anyone wandering where the history prop comes from:
Main app entry point (in webpack.config.js). src/main.js:
import React from 'react'
import ReactDOM from 'react-dom'
import createStore from './store/createStore'
import { hot } from 'react-hot-loader'
import AppContainer from './containers/AppContainer'
import { persistStore } from 'redux-persist'
// ========================================================
// Store Instantiation
// ========================================================
const initialState = window.___INITIAL_STATE__
const { history, store } = createStore(initialState)
// begin periodically persisting the store
let persistor = persistStore(store)
// ========================================================
// Render Setup
// ========================================================
const MOUNT_NODE = document.getElementById('root')
let render = () => {
ReactDOM.render(
<AppContainer store={store} persistor={persistor} history={history} />,
MOUNT_NODE
)
}
// This code is excluded from production bundle
if (__DEV__) {
if (module.hot) {
// Development render functions
const renderApp = render
const renderError = (error) => {
const RedBox = require('redbox-react').default
ReactDOM.render(<RedBox error={error} />, MOUNT_NODE)
}
// Wrap render in try/catch
render = () => {
try {
renderApp()
} catch (error) {
console.error(error)
renderError(error)
}
}
// Setup hot module replacement
module.hot.accept('./containers/AppContainer', () =>
render(require('./containers/AppContainer').default)
)
}
}
// ========================================================
// Go!
// ========================================================
export default hot(module)(render)
render()
createStore.js:
import { applyMiddleware, compose, createStore } from 'redux'
import thunk from 'redux-thunk'
import { apiMiddleware } from 'redux-api-middleware'
import { createLogger } from 'redux-logger'
import makeRootReducer from './reducers'
import { routerMiddleware } from 'react-router-redux'
// I18n
import { syncTranslationWithStore, loadTranslations, setLocale } from 'react-redux-i18n'
import { translationsObject } from 'translations/index'
// Router history
import createHistory from 'history/createBrowserHistory'
// Raven for Sentry
import Raven from 'raven-js'
import createRavenMiddleware from 'raven-for-redux'
export default (initialState = {}) => {
// ======================================================
// Middleware Configuration
// ======================================================
const logger = createLogger()
const history = createHistory()
const historyMiddleware = routerMiddleware(history)
const middleware = [historyMiddleware, apiMiddleware, thunk, logger]
if (__PROD__) {
Raven.config(`${__SENTRY_DSN__}`).install()
middleware.push(createRavenMiddleware(Raven))
}
// ======================================================
// Store Enhancers
// ======================================================
const enhancers = []
let composeEnhancers = compose
const composeWithDevToolsExtension = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
if (typeof composeWithDevToolsExtension === 'function') {
composeEnhancers = composeWithDevToolsExtension
}
// ======================================================
// Store Instantiation and HMR Setup
// ======================================================
const store = createStore(
makeRootReducer(),
initialState,
composeEnhancers(
applyMiddleware(...middleware),
...enhancers
)
)
store.asyncReducers = {}
// DEPRECATED in react-router v4: To unsubscribe, invoke `store.unsubscribeHistory()` anytime
// store.unsubscribeHistory = browserHistory.listen(updateLocation(store))
if (module.hot) {
const reducers = require('./reducers').default
module.hot.accept('./reducers', () => {
store.replaceReducer(reducers(store.asyncReducers))
})
}
syncTranslationWithStore(store)
store.dispatch(loadTranslations(translationsObject))
store.dispatch(setLocale('es_AR'))
return { history, store }
}

react router not rendering the component when using redux

I am learning react and redux.I am building a mock up project ,While running the project there is no error however nothing is rendered when I click the home route,
my container code,
import Home from '../components/Home.js'
import {
editorContentUpdated
} from '../action/index.js'
const mapStateToProps = (state) => {
return {
editorText: state.editorText
};
}
const mapDispatchToProps = (dispatch) => {
console.log('here')
onBlur: (text) => {
console.log('text', text);
dispatch(editorContentUpdated(text));
}
}
export default (mapStateToProps, mapDispatchToProps)(Home);
reducer code,
const editorReducer = (state, action) =>{
if(state == undefined){
return null
}
console.log('editorReducer',action.payload);
switch(action.type){
case 'EDITOR_SELECTED':
return action.payload
break;
case 'CONTENT_UPDATED':
return action.payload
break;
}
return state;
}
export default editorReducer;
action creater,
export const getPreviewContent = (text) =>{
console.log('previewContent', text);
return{
type:'PREVIEW_SELECTED',
data:text
}
}
export const editorContentUpdated =(text) =>{
console.log('editor content', text);
return {
type:'CONTENT_UPDATED',
data:text
}
}
routes.js file,
import React from 'react'
import{Router,Route,IndexRoute,browserHistory} from 'react-router'
import Layout from '../components/Layout.js'
import Home from '../container/editor.js'
import Preview from '../components/Preview.js'
const routes = (
<Router history={browserHistory}>
<Route path='/' component={Layout}>
<IndexRoute component={Home} />
<Route path='preview' component={Preview} />
</Route>
</Router>
);
export default routes;
layout,
import React from 'react'
import {
Link
} from 'react-router'
import {
connect
} from 'react-redux'
var Layout = React.createClass({
render: function() {
var styles = {
paddingRight: '10px'
}
console.log('custom', this.props.custom);
var custom = this.props.custom;
return ( <html >
<head >
<title > {custom.title} < /title> <link rel = 'stylesheet href = '/style.css' / >
</head> <body >
<nav >
<Link style = {styles
}to = '/' > Home < /Link> <
Link to = '/preview' > Preview < /Link> </nav> {
this.props.children
}<script dangerouslySetInnerHTML = {{
__html: 'window.PROPS=' + JSON.stringify(custom)
}}/> <script src = '/bundle.js' / >
</body> </html>);}
});
var wrapper = connect(
function(state) {
return {
custom: state
};
}
);
export default wrapper(Layout);
Home Component,
import React from 'react'
import {
Link
} from 'react-router'
let Home = React.createClass({
getInitialState: function() {
return {
editorText: ''
}
},
updateText: function(event) {
this.setState({
editorText: event.target.value
})
},
render: function() {
let wrapperStyle = {
width: '100%'
}
let editorStyle = {
float: 'left',
width: '50%',
height: 'auto'
}
let previewBoxStyle = {
float: 'left',
height: 'auto',
width: '50%'
}
return ( <
div style = {
wrapperStyle
} >
<
div style = { editorStyle} >
<textarea rows = '10' cols = '50'onChange = {this.updateText}
value = {this.props.editorText}/> </div> </div>);}
});
There is no error in the console, but the home component is not rendered when I click on the home button,Could anyone suggest me where I am going wrong?
In your Home component I cannot see an you exporting the component and hence The component won't be rendered
export the Home component as
export default Home;
Also when you make use of react-redux you need to make the store available to your Components, for that you need to make use of Provider
import { Provider } from 'react-redux'
import React from 'react'
import{Router,Route,IndexRoute,browserHistory} from 'react-router'
import Layout from '../components/Layout.js'
import Home from '../container/editor.js'
import Preview from '../components/Preview.js'
import { createStore } from 'redux'
import EditorReducer from '/path/to/reducer';
....
const store = createStore(EditorReducer )
const routes = (
<Provider store={store}>
<Router history={browserHistory}>
<Route path='/' component={Layout}>
<IndexRoute component={Home} />
<Route path='preview' component={Preview} />
</Route>
</Router>
</Provider>
);
export default routes;

Resources