Giter VIP home page Giter VIP logo

connected-react-router's Introduction

Breaking change in v5.0.0! Please read How to migrate from v4 to v5/v6.

v6.0.0 requires React v16.4.0 and React Redux v6.0 / v7.0.

Connected React Router Build Status Open Source Helpers

A Redux binding for React Router v4 and v5

Main features

โœจ Synchronize router state with redux store through uni-directional flow (i.e. history -> store -> router -> components).

๐ŸŽ Supports React Router v4 and v5.

โ˜€๏ธ Supports functional component hot reloading while preserving state (with react-hot-reload).

๐ŸŽ‰ Dispatching of history methods (push, replace, go, goBack, goForward) works for both redux-thunk and redux-saga.

โ›„ Nested children can access routing state such as the current location directly with react-redux's connect.

๐Ÿ•˜ Supports time traveling in Redux DevTools.

๐Ÿ’Ž Supports Immutable.js

๐Ÿ’ช Supports TypeScript

Installation

Connected React Router requires React 16.4 and React Redux 6.0 or later.

npm install --save connected-react-router

Or

yarn add connected-react-router

Usage

Step 1

In your root reducer file,

  • Create a function that takes history as an argument and returns a root reducer.
  • Add router reducer into root reducer by passing history to connectRouter.
  • Note: The key MUST be router.
// reducers.js
import { combineReducers } from 'redux'
import { connectRouter } from 'connected-react-router'

const createRootReducer = (history) => combineReducers({
  router: connectRouter(history),
  ... // rest of your reducers
})
export default createRootReducer

Step 2

When creating a Redux store,

  • Create a history object.
  • Provide the created history to the root reducer creator.
  • Use routerMiddleware(history) if you want to dispatch history actions (e.g. to change URL with push('/path/to/somewhere')).
// configureStore.js
...
import { createBrowserHistory } from 'history'
import { applyMiddleware, compose, createStore } from 'redux'
import { routerMiddleware } from 'connected-react-router'
import createRootReducer from './reducers'
...
export const history = createBrowserHistory()

export default function configureStore(preloadedState) {
  const store = createStore(
    createRootReducer(history), // root reducer with router state
    preloadedState,
    compose(
      applyMiddleware(
        routerMiddleware(history), // for dispatching history actions
        // ... other middlewares ...
      ),
    ),
  )

  return store
}

Step 3

  • Wrap your react-router v4/v5 routing with ConnectedRouter and pass the history object as a prop. Remember to delete any usage of BrowserRouter or NativeRouter as leaving this in will cause problems synchronising the state.
  • Place ConnectedRouter as a child of react-redux's Provider.
  • N.B. If doing server-side rendering, you should still use the StaticRouter from react-router on the server.
// index.js
...
import { Provider } from 'react-redux'
import { Route, Switch } from 'react-router' // react-router v4/v5
import { ConnectedRouter } from 'connected-react-router'
import configureStore, { history } from './configureStore'
...
const store = configureStore(/* provide initial state if any */)

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}> { /* place ConnectedRouter under Provider */ }
      <> { /* your usual react-router v4/v5 routing */ }
        <Switch>
          <Route exact path="/" render={() => (<div>Match</div>)} />
          <Route render={() => (<div>Miss</div>)} />
        </Switch>
      </>
    </ConnectedRouter>
  </Provider>,
  document.getElementById('react-root')
)

Note: the history object provided to router reducer, routerMiddleware, and ConnectedRouter component must be the same history object.

Now, it's ready to work!

Examples

See the examples folder

Build

npm run build

Generated files will be in the lib folder.

Development

When testing the example apps with npm link or yarn link, you should explicitly provide the same Context to both Provider and ConnectedRouter to make sure that the ConnectedRouter doesn't pick up a different ReactReduxContext from a different node_modules folder.

In index.js.

...
import { Provider, ReactReduxContext } from 'react-redux'
...
      <Provider store={store} context={ReactReduxContext}>
        <App history={history} context={ReactReduxContext} />
      </Provider>
...

In App.js,

...
const App = ({ history, context }) => {
  return (
    <ConnectedRouter history={history} context={context}>
      { routes }
    </ConnectedRouter>
  )
}
...

Contributors

See Contributors and Acknowledge.

License

MIT License

connected-react-router's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

connected-react-router's Issues

@@router/LOCATION_CHANGE fires twice

The first listener subscribes in syncHistoryWithStore and the second in ConnectedRouter constructor.
Is it correct to fire this action twice on each transition?

Example for query strings needed

Hi

Could you please provide an example how to deal with query strings please.

/list?id=5&sort=true

how would a <Route> look like that matches and how to extract the params id and sort?

Collaboration

Hey @supasate. I was thinking of just emailing you, but I'd rather have this transparent and out in the open.

I'm working on Redux integration for React Router 4.0 (to be released shortly!) and have a preliminary PR in progress here (also to be released shortly!): remix-run/react-router#4668

It's really just a minimal skeleton of what the project will eventually be (hence it's getting released as an alpha). I know this project is more feature-complete and has some interesting ideas. What do you think about bringing those over to react-router-redux and working on them together under the main monorepo?

And if that sounds like a good idea, what sort of things have you learned in bringing the react-router-redux stuff to Router 4.0? What are the biggest caveats that you still have to work through (if any)? I know this stuff is tough, so I feel your pain! ๐Ÿ˜„

Also, feel free to email me directly ([email protected]) if you want to discuss anything in private.

Browser history stack is modified when time travelling

Currently, when we do time travelling, the ConnectedRouter tries to change the URL bar to match the router state in the redux store (which is changed by Redux DevTools) by using history.push (see here).

This method seems to work fine, however, internally, the real browser history stack is modified (new history is pushed on top of the stack). It would be better if we can change the URL by just moving the pointer in the history stack to match time travelling.

Initial page load

Sorry if this is a basic question, but I couldn't find an answer, and I'm new to react/redux/router.

When the page loads initially, this module doesn't seem to dispatch any redux action. I have a URL, say /user/add, which displays a form to add a new user. When this URL is hit, I want to create a dummy user object with default values in the state, for the purposes of displaying the form correctly and holding it's data temporarily.

The above works fine if I navigate to the URL from other parts of my app, and the LOCATION_CHANGE action is dispatched correctly. However, if this URL was the first page loaded in the app, the LOCATION_CHANGE action isn't fired, which prevents me from setting up the dummy state, causing my app to break.

Is this is the expected behaviour? If so, what's the recommended workaround for handing my case?

I've tried explicitly calling history.push(location.pathname) on page load, and while that does the trick, it has the effect of appending to history, which is not what I want.

I'm using a static server as a backend (no server rendering), and want to stick with stateless functional components if I can.

Update peer dependency to Redux v4

There is any known issue in update the peer dependency to Redux v4? Anyone would mind if I make a pull request to update Redux peer dependency to version 4?

Doesn't support "basename" prop correct

Hi,

I have a problem when switching from "BrowserRouter" to your "ConnectedRouter".
On the router I have the prop "basename" set to "/foo/". So i want all my routes to be prefixed with /foo. For example "/foo/bar".
The connected router ignores the basename and serves all routes from /

Initial Route Not Recorded In Actions

More of a request than a bug.

I could be wrong but currently it looks like the initial route is gotten through the initial state of the reducer. This means it is not recorded in the actions history exported by redux-dev-tools. So importing the history and time traveling wont work properly unless you import in the same initial route as it was recorded in.

Could we initially dispatch a location-change action with the initial route so the initial route is recorded in the action history.

How can I access the params

I managed to make this work in my project, however, I don't see params.
location: hash:"" key:"aymkl8" pathname: "/about/mo/18HHaYQSUs6WUWIOMaYYiI" search:""

I need to access the id (18HHaYQSUs6WUWIOMaYYiI) in MapStateToProps. I see the id in the params normally inside the component.

Webpack 2?

Since all the stuff here is currently in non-release phase, don't you think you can create examples with Webpack2 (which is beta as well)?

It looks like hot reloading of App component should become easier (less code in index.js)

How to access route params?

Hey,
I'm having a hard time figuring out how to work with multiple sub-routers.
I have two components that get called from deferent sub-routers but both rely on the same routepath. I want to use the redux-store to save the route parameters so I won't need to explicitly pass the props down to all children (I have many components down the tree), But I can't decide how and who is responsible to update this key in the store.
What is the best way to model this kind of behaviour?

Add react-router as a peer dependency

With webpack, react-router is being bundled twice when using connected-react-router. I guess it should be a peer dependency rather than a dependency, right?

Params from match in redux store

I would love to use the params in the store form the router.
Now i only know the pathname and i need to do filtering to get the param i gave in the Route component.

Example:

// I only need "blogSlug" as a parameter. But i get the whole path.
<Route exact path="/item/:blogSlug" />

react-router-redux is deprecated

Hi @supasate !

now when react-router-redux is deprecated you proably would be the best alternative
remix-run/react-router@b1a77bc

the main concern about this project - it was not updated for a long time. please tell us about your plans? is this project still alive? can we expect updates?

PS and if yes, it would be good to have SSR because its the only thing missinng from RRR functionality

Add unit tests

Add tests for several scenarios such as checking whether it creates redux actions when history has been changed.

Todos

  • Test action creators (#11)
  • Test reducer (#12)
  • Test middleware (#14)
  • Test ConnectedRouter(#20)

Navigate through a custom action

Hi,

I would like to dispatch a single action that updates both: search (query string in the url) and other part of the regular (not router-related) redux state. Is it possible?

I would like to keep it as a single action, so components will receive all new props at once.

Best,
Marek

Route not changing - react-router 4.0.0

Was working great, but seems to be some issue with the new 4.0.0 release of react-router...
Maybe I should be posting there...

I am mostly navigating with push
@@router/LOCATION_CHANGE actions are firing, URL bar is changing, but Switch doesn't appear to be matching...

Works on first load, but dispatching push just seems to change the URL...

Not getting any errors, just no routing! ๐Ÿ˜ข

Help is much appreciated!

Warning: forceUpdate

I want the connected-react-router functionalitty to integrate my app better with redux-obeservables.
All works but I keep seeing the force Update error

// store.tsx
export const store = (history) => {
    if (Utils.isServer()) {
        return createStore(allReducers, FlagDefaultStore, applyMiddleware(Epics))
    } else {
        let hhh = connectRouter(history)(allReducers);
        let DEV_TOOL = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
        let composeEnhancers = DEV_TOOL || compose;
        let mid = applyMiddleware(routerMiddleware(history), Epics);
        let middleware = composeEnhancers(mid);
        return createStore(hhh, FlagDefaultStore, middleware)
    }
};
// client.tsx
const renderApp = NextApp => {
    const history = createBrowserHistory();
    let app = <AppContainer>
        <WithStylesContext onInsertCss={styles => styles._insertCss()}>
            <MuiThemeProvider muiTheme={theme}>
                <Provider store={store(history)}>
                    <ConnectedRouter history={history}>
                        {NextApp}
                    </ConnectedRouter>
                </Provider>
            </MuiThemeProvider>
        </WithStylesContext>
    </AppContainer>;
    withAsyncComponents(app).then(({appWithAsyncComponents}) =>
        render(appWithAsyncComponents, document.getElementById("container")),
    );
};

renderApp(FlagApp({userAgent: navigator.userAgent}));
// app.tsx
export default ({userAgent}) => {
    //noinspection TypeScriptUnresolvedVariable
    return (
        <div>
            <Route component={AppShell}/>
            <Route component={ProgressBar}/>
            <Switch>
                <Route exact path="/" component={AsyncLogin(userAgent)}/>
                <Route path="/dashboard" component={AsyncDashboard(userAgent)}/>
                <Route component={NoMatch}/>
            </Switch>
        </div>)
}

Working with v4-alt of react-router

Looks like StaticRouter is gone, any ideas how to proceed? First time diving into v4 code base so not exactly sure what the change means in terms of required updates.

In Time Travel, URL is only updated if the path changes, the search is ignored

The [current version of the code] only compares the pathname part of the location, to detect time travel debugging, but it totally ignores the search part of the location. (ie. ?foo=bar)

Therefore, if during time travel, the only changes in the URL happen in the search part, the change is ignored, and the URL is not updated.

It would be nice to fix this. (One simply has to check the search part too, it's pretty much works the same way.)

Access match object in reducer

It doesn't seem like it is possible to access the match object in the reducer. Should there be a way to connect a specific Route so that its state is saved to the reducer as well? Something like

import { ConnectedRouter, ConnectedRoute } from 'connected-react-router'
...
<ConnectedRouter history={history}>
  <ConnectedRoute path='/example/:willshow' />
  <Route path='/example/:wontshow' />
</ConnectedRouter>

that would generate the state

{
  history: {
    location: {
      path: '/example/somevalue'
    }
  },
  match: {
    params: {
      willshow: 'somevalue'
    },
    // ... React-Router match object (from https://reacttraining.com/react-router/#match)
  }
} 

This would basically make the reducer state be the same as the Router object received from the withRouter connector.

router.location is null on pageload

@supasate Thanks for your effort on this project, giving it a whirl to see how it goes.

I'm unsure if this is the intended behavior, but it seems that router.location is null in state until I actually navigate with a Link helper, at which point it populates with the expected data.

Is there a way to ensure this data is present on pageload from the initial route, or am I doing something wrong?

Cheers!

Using with Immutable.js

Does this library support using Immutable.js with Redux?
If not, it would be nice to add it.

Question on react-router docs about redux "deep integration"

The docs https://reacttraining.com/react-router/web/guides/redux-integration state:

captura de pantalla 2018-07-04 a la s 19 20 58

I have my app which uses redux, and the store has an array ok books indexed by id.

On BookDetails ( a connected component) i had the selected book id on the state, so i could get the full book instance, and render its title; ie:

<AppBar>
  <BookTitle />
</AppBar>
<BookDetails />
class BookDetails ...

const mapStateToProps = (state) => {
  const id = state.ui.selected_id;
  return {
    bookDetails: state.books.find(b => b.id == id)
  };
};

I have other component on the hierarchy which was also connected in a similar way, and shows the title inside the global

class BookTitle ...

const mapStateToProps = (state) => {
  const id = state.ui.selected_id;
  return {
    title: state.books.find(b => b.id == id).title
  };
};

Now trying to integrate react-router (migrating away from having the selected book id on the store, to having now the router/match, etc) to point to the selected book. So, i would have some like:

<AppBar>
  <BookTitle />
</AppBar>
<Route path='/book/:id' component={BookDetails} />
class BookDetails ...

const mapStateToProps = (state, ownProps) => {
  const id = ownProps.match.params.id;
  return {
    bookDetails: state.books.find(b => b.id == id)
  };
};

And also:

class BookTitle ...

const mapStateToProps = (state, ownProps) => {
  const id = ownProps.match.params.id;   // WRONG! there is no match... so...
  return {
    title: state.books.find(b => b.id == id).title
  };
};

In this case, as <BookTitle /> is not part of any <Route path= ... /> then i cannot access ownProps.match.params.id ... and then cannot know which is the selected id.... etc

if i want to avoid using connected-react-router as the docs try to convince me, how would be The Way to access the book instance on , given the current location from react-router?

Current location not updating with redux-persist setup

With the redux-persist setup I'm using below the router.location parameter in redux state doesn't update when navigating using the react-router NavLink. The location in the browser does update as it should. Has anyone else come across this issue? Is the configuration below correct?

configureStore.js

import { createStore, applyMiddleware, compose } from "redux";
import { connectRouter, routerMiddleware } from "connected-react-router";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";

import rootReducer from "./reducers/index";

const persistConfig = {
  key: "root",
  storage
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

export default (initialState = {}, history) => {
  const middlewares = [routerMiddleware(history)];

  const enhancers = [applyMiddleware(...middlewares)];

  const composeEnhancers =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

  const store = createStore(
    connectRouter(history)(persistedReducer),
    composeEnhancers(...enhancers)
  );

  const persistor = persistStore(store);

  return { store, persistor };
};

index.js

import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { ConnectedRouter } from "connected-react-router";
import createHistory from "history/createBrowserHistory";

import configureStore from "./configureStore";

import App from "./app";

const initialState = {};

const history = createHistory();

const { store, persistor } = configureStore(initialState, history);

const MOUNT_NODE = document.getElementById("root");

render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <ConnectedRouter history={history}>
        <App />
      </ConnectedRouter>
    </PersistGate>
  </Provider>,
  MOUNT_NODE
);

Uncaught TypeError: Cannot read property 'pathname' of undefined

This happens to me when using HMR (only after I chnage something I'm working on). Strange enough but this happend on any action

2017-05-24 18_18_09-mahjong backend_ player dashboard

I did not notice such behaviour with previous versions.

From package.json:

{
    "connected-react-router": "^4.2.1",
    "react-router": "^4.1.1",
    "react-router-dom": "^4.1.1",
}

React.StrictMode warnings

componentWillMount: Please update the following components to use componentDidMount instead: ConnectedRouter, Route, Router, Switch

History seems to be a necessary peer dependency at a certain version

Hey guys! Just went through doing some major upgrades with our system.

I'm in the process of installing connected-react-router from an old version of react-router-redux where I had an old history version (v2). For connected-react-router to work with history, I needed to upgrade to the latest version of history (v4).

Suggested change: add history version 4+ as a peerDependency.

I'm not confident enough to propose the change as a PR, but thought to bring this up just in case. I think this is true though.

P.S. in the Readme, the link for Support React Router v4. is a 404 now.

Make release compatible with redux 4

Hi. I noticed you upped compatibility with Redux 4.

Is it possible to make a maintenance release for this? Redux 4 is quite a change from 3.x.

Cant run basic example

I'm running yarn and then npm run dev but I receive the following errors:

> [email protected] dev /Users/***/Documents/connected-react-router/examples/basic
> node server.js

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE :::8080
    at Object.exports._errnoException (util.js:1022:11)
    at exports._exceptionWithHostPort (util.js:1045:20)
    at Server._listen2 (net.js:1262:14)
    at listen (net.js:1298:10)
    at Server.listen (net.js:1376:9)
    at Function.listen (/Users/ms0366/Documents/connected-react-router/examples/basic/node_modules/express/lib/application.js:617:24)
    at Object.<anonymous> (/Users/***/Documents/connected-react-router/examples/basic/server.js:22:5)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)

npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/Cellar/node/7.4.0/bin/node" "/usr/local/bin/npm" "run" "dev"
npm ERR! node v7.4.0
npm ERR! npm  v4.3.0
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] dev: `node server.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] dev script 'node server.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the connected-react-router-example-basic package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node server.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs connected-react-router-example-basic
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls connected-react-router-example-basic
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/***/.npm/_logs/2017-03-06T19_14_06_653Z-debug.log

I also leave the log as requested.

2017-03-06T19_14_06_653Z-debug.log.zip

How to determine if I can use goBack()

I tried to do this: when I open my page, check for history.length and either use goBack() action if history.length > 1 or some fallbackAction otherwise.

This works on first page open.

But if page has forward actions and no back actions, history.length > 1 is true (it might be 3, 4, etc...), but there is no possibility to goBack and my goBack button looks broken (nothing happens for end usereven though goBack() action is dispatched)

Is there an easy way to check back history length?
Looks like react-router issue, but I decided to start from here.

P.S. I'm using browser history (createBrowserHistory from 'history')

Deploy to Subdirectory

The sysadmin on our team needs to deploy our app to a subdirectory of the root url, rather than a subdomain (as I've always done it in the past).

I found various guides on how to do this with react-router, but nothing for this package.

Is there a straightforward way to do this? And if not...is there a roundabout way? ;)

Thanks!

Using Immutable.js Record as state

Hello,

I am using the Record object from Immutable.js, however there is no filterNot function as there is for the Map type. Is there a recommended way of using connected-react-router with the Record type?

ConnectedRouter incompatible with app shell offline pattern

Trying to create a site using the app shell pattern with SSR+offline capability

eg
https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route
https://michaljanaszek.com/blog/combine-pwa-and-isomorphic-rendering
GoogleChrome/workbox#796

A core tenet of this pattern is

Whenever a user goes to your site in the browser, the request for the page will be a navigation request and will be served the cached page '/single-page-app.html'.

Driven by respondWith
https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith

Note that navigation requests for Windows and iframes do NOT use the final URL. The way the HTML specification handles redirects for navigations ends up using the request URL for the resulting Window.location. This means sites can still provide an "alternate" view of a web page when offline without changing the user-visible URL.

If I

  • navigate to /go/about
  • Then go offline
  • Then try /go/about again while offline
  • A /shell page should be rendered from cache
  • While the browser address bar URL stays as /go/about

This code within ConnectedRouter seems to prevent the above pattern
https://github.com/supasate/connected-react-router/blob/master/src/ConnectedRouter.js#L38-L46

Dumping the variables
image
image

If I comment out those line, I can get the service worker correctly showing the /shell page content while staying on the /go/about page when offline.

Thoughts on how to solve this?

  • Component prop to disable the time-travel functionality (eg history.push)?
  • Somehow update store.state.router.location depending on if the content was rendered normally or from FetchEvent.respondWith override (service worker cache)?

Uncaught TypeError: e.history.listen is not a function

I use aps.net mvc so I use UMD to include js files:
history.min.js
prop-types.min.js
react.development.js
react-dom.development.js
redux.min.js
react-redux.min.js
https://unpkg.com/[email protected]/umd/react-router.min.js
react-router-dom.min.js
ConnectedReactRouter.min.js


js code:

  const counterReducer = (state = 0, action) => {
    switch (action.type) {
      case 'INCREMENT':
        return state + 1
      case 'DECREMENT':
        return state - 1
      default:
        return state
    }
  };
  rootReducer = combineReducers({
    count: counterReducer,
  })
  
  const history = createBrowserHistory();
  const store = createStore(
  connectRouter(history)(rootReducer),
  compose/*composeEnhancer*/(
    applyMiddleware(
      routerMiddleware(history),
    ),
  ),
)
ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}> { /* place ConnectedRouter under Provider */ }
      <div> { /* your usual react-router v4 routing */ }
        <Switch>
          <Route exact path="/" render={() => (<div>Match</div>)} />
          <Route render={() => (<div>Miss</div>)} />
        </Switch>
      </div>
    </ConnectedRouter>
  </Provider>,
  document.getElementById('root')
)
`
----------
Uncaught TypeError: e.history.listen is not a function.

Include history.length in redux state

The history object has a length property which isn't reflected in the redux state.

I want to add a simple back button to my electron app and knowing when history.length == 0 would allow me to disable the button.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.