:tada: Redux First History - Redux history binding support react-router - @reach/router - wouter

Overview

redux-first-history


Redux First History - Make Redux 100% SINGLE-AND-ONLY source of truth!

Redux history binding for

Compatible with immer - redux-immer - redux-immutable.

🎉 A smaller, faster, optionated, issue-free alternative to connected-react-router

Main Goal

Use whatever you like. History will just work as it should.

//react-router v4 - v5
this.context.router.history.location === state.router.location
this.context.route.location === state.router.location
this.props.history.location === state.router.location
this.props.location === state.router.location
withRouter.props.location === state.router.location

//@reach/router
this.props.location === state.router.location

//wouter - pathname
useLocation()[0] === state.router.location.pathname

You can mix redux, redux-saga, react-router, @reach/router & wouter without any synchronization issue!
Why? Because there is no synchronization at all! There is only one history: reduxHistory!

  • one way data-flow
  • one unique source of truth
  • no more location issue!

Edit Redux-First Router Demo

Demo : https://wy5qw1125l.codesandbox.io/ src: https://codesandbox.io/s/wy5qw1125l

Main features

  • 100% one source of truth (store)
  • No syncronization depending on rendering lifecicle (ConnectedRouter)
  • No React dependency (we want history to be always in store!)
  • 100% one-way data flow (only dispatch actions!)
  • improve React shallowCompare as there is only one "location"
  • support react-router v4 / v5 / v6
  • support @reach/router 1.x
  • support @wouter 2.x
  • support mix react-router, @reach-router & wouter in the same app!
  • fast migration from existing project, with same LOCATION_CHANGE and push actions (taken from RRR)
  • handle Redux Travelling from devTools (that's a non sense in production, but at the end of the day this decision it's up to you ...)

Installation

Using npm:

$ npm install --save redux-first-history

Or yarn:

$ yarn add redux-first-history

Usage

store.js

import { createStore, combineReducers, applyMiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import { createReduxHistoryContext, reachify } from "redux-first-history";
import { createWouterHook } from "redux-first-history/wouter";
import { createBrowserHistory } from 'history';

const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 
  history: createBrowserHistory(),
  //other options if needed 
});

export const store = createStore(
  combineReducers({
    router: routerReducer
    //... reducers //your reducers!
  }),
  composeWithDevTools(
    applyMiddleware(routerMiddleware)
  )
);

export const history = createReduxHistory(store);
//if you use @reach/router 
export const reachHistory = reachify(history);
//if you use wouter
export const wouterUseLocation = createWouterHook(history);

app.js

import React, { Component } from "react";
import { Provider, connect } from "react-redux";
import { push } from "redux-first-history";
import { Router } from "react-router-dom";
import { store, history } from "./store";

const App = () => (
      <Provider store={store}>
        <Router history={history}>
        //.....
        </Router>
      </Provider>
    );

export default App;
  • just simple Router with no more ConnectedRouter!
  • use push action creator from redux-first-history if you need to dispatch location from saga or connected components.
  • Probably, you already did it with react-router-redux or connected-react-router (in this case you have only to replace the import!)

Abstract

While working with relatively large projects, it's quite common to use both redux and react-router.

So you may have components that take location from store, others that take location from router context, and others from withRouter HOC.

This sometimes could generate sync issue, due to the fact that many components are updated at different time. In addition, React shallowCompare rendering optimization will not work as it should.

With redux-first-history, you can mix components that get history from wherever, they will always be tunneled to state.router.location !

Options

export const createReduxHistoryContext = ({
  history, 
  routerReducerKey = 'router', 
  oldLocationChangePayload = false, 
  reduxTravelling = false, 
  selectRouterState = null,
  savePreviousLocations = 0,
  batch = null,
  reachGlobalHistory = null
})
key optional description
history no The createBrowserHistory object - currently tested only with version 4.7.2 - 4.10.1
routerReducerKey yes if you don't like router name for reducer.
oldLocationChangePayload yes if you use the oldLOCATION_CHANGEpayload{ ...location }instead of the new{ location }, setting this flag will make you able to not change your app at all! (removed in v5)
reduxTravelling yes if you want to play with redux-dev-tools :D.
selectRouterState yes custom selector for router state. With redux-immutable selectRouterState = state => state.get("router")
savePreviousLocations yes if > 0 add the key "previousLocation" to state.router, with the last N locations. [{location,action}, ...]
batch yes a batch function for batching states updates with history updates. Prevent top-down updates on react : usage import { unstable_batchedUpdates } from 'react-dom'; batch = unstable_batchedUpdates
reachGlobalHistory yes globalHistory object from @reach/router - support imperatively navigate of @reach/router - import { navigate } from '@reach/router' : usage import { globalHistory } from '@reach/router'; reachGlobalHistory = globalHistory

Advanced config

  • support "navigate" from @reach/router
import { createReduxHistoryContext, reachify } from "redux-first-history";
import { createBrowserHistory } from 'history';
import { globalHistory } from '@reach/router';

const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 
  history: createBrowserHistory(),
  reachGlobalHistory: globalHistory,
  //other options if needed 
});
  • React batch updates: top-down batch updates for maximum performance. Fix also some update edge cases.
import { createReduxHistoryContext, reachify } from "redux-first-history";
import { createBrowserHistory } from 'history';
import { unstable_batchedUpdates } from 'react-dom';

const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 
  history: createBrowserHistory(),
  batch: unstable_batchedUpdates,
  //other options if needed 
});

Feedback

Let me know what do you think!
Enjoy it? Star this project! :D

credits & inspiration

  • redux-first-routing
  • react-router-redux
  • connected-react-router

Contributors

See Contributors.

License

MIT License.

Comments
  • Roadmap 5.x

    Roadmap 5.x

    Roadmap 5.x

    This issue is a roadmap for all work on the 5.x branch.

    • [x] Rewrite all with TS
    • [x] Support history v5.x
    • [x] Support react-router v6.x
    • [x] Deprecate/remove oldLocationChangePayload
    • [x] Test coverage 100%
    • [x] Better docs

    if you have any ideas... now's the time! Let's discuss.

    help wanted 
    opened by salvoravida 21
  • Feature Suggestion: add an optional `pathnameHistory` array to the `router` state

    Feature Suggestion: add an optional `pathnameHistory` array to the `router` state

    In an app I'm building, I needed to know the previous url to properly animate certain transitions. I've been using redux-first-history for many months now (thanks for maintaining this library!) and assumed that it would have a history array within the generated reducer state, given the name of the library - but it doesn't.

    I've built a little ContextProvider for my own app using the location: { pathname } from redux-first-history that simply maintains the current pathname and the previous pathname. I think redux-first-history could become more useful to more people if it simply pushed the current pathname to a pathnameHistory array in the state (optionally enabled with a flag) every time the location changed (and popped the last pathname whenever a user goes back). Seems like something very simple to implement that could be useful for particular applications. :)

    Or at the very least - some equivalent of document.referrer (which doesn't really exist in the context of a Single Page App) would go a long way.

    I'm happy with my own Context centric solution, but I figured I'd share this thoughts here in case it resonated with anybody else. :)

    opened by thisissami 8
  • Remove react router basename from LOCATION_CHANGE redux action pathname

    Remove react router basename from LOCATION_CHANGE redux action pathname

    I would like the react router basename, if set, to be removed from payload.location.pathname in LOCATION_CHANGE redux actions created by router navigation.

    I would also like push(LOCATION_CHANGE) to navigate to the correct place in the router, when the basename is omitted from payload.location.pathname.

    This is related to https://github.com/salvoravida/redux-first-history/issues/87

    opened by steinarb 7
  • <Navigate> with React 18 causes

    with React 18 causes "Maximum update depth exceeded"

    This error seems to occur under very specific circumstances: CodeSandbox example

    • Navigating to /redirect using either
      • The third <NavLink/>
      • "Native Navigate" using useNavigate() hook
      • "Navigate with Redux" using dispatch(push(..))
      • Navigating to /redirect using the address bar (in the CodeSandbox browser)

    will crash the App and display

    Error

    Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

    Modifications to the Example that will stop the App from crashing

    • Using render from "react-dom" instead of createRoot() in index.tsx, the app will behave as if it's running React 17
    • Using useNavigate() instead of <Navigate/> (swap the <Route/> for /redirect in MainContent.tsx with the commented one, which uses <NavigateWithHook/>)
    • Not using redux-first-history, for example by replacing <HistoryRouter> with <BrowserRouter/> in App.tsx from react-router-dom
    • And strangely using useLocation() instead of useSelector() in MainContent.tsx with the state of the router

    Modifications to the Example that will NOT stop the App from crashing

    • <StrictMode/> in React 18 unmounts and remounts every component once after the initial render in dev mode. But disabling Strict Mode in index.tsx will still cause the app to crash
    opened by frankruegamer 7
  • Cannot read properties of undefined (reading 'pathname'). problem when I click other Link from the page

    Cannot read properties of undefined (reading 'pathname'). problem when I click other Link from the page

    Hello.

    I am using this library, and I have problem with it. I am using it with react-route v6. the version of this library is 5.0.8 I have same config than in the example, but when I change between webpages, i see this: Screen Shot 2022-03-01 at 15 40 31

    my store is:

    import { createStore, combineReducers, applyMiddleware } from 'redux';
    import { composeWithDevTools } from 'redux-devtools-extension';
    import createSagaMiddleware from 'redux-saga';
    import { createBrowserHistory } from 'history';
    import { createReduxHistoryContext } from 'redux-first-history';
    import { redesign } from './redesign/redux/reducers';
    import { v04 } from './redesign/redux/reducers/v04';
    import sagas from './sagas';
    
    const sagaMiddleware = createSagaMiddleware();
    const historyApi = createBrowserHistory();
    
    const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({
      history: historyApi,
      savePreviousLocations: 10
    });
    
    export const store = createStore(
      combineReducers({
        router: routerReducer,
        redesign,
        v04
      }),
      composeWithDevTools(
        applyMiddleware(sagaMiddleware),
        applyMiddleware(routerMiddleware)
      )
    );
    
    sagaMiddleware.run(sagas);
    export const history = createReduxHistory(store);
    

    The router is like:

    import { history } from './store';
    import { HistoryRouter as Router } from 'redux-first-history/rr6';
    
    const App = () => {
      return (
       <Router history={history}>
          ...
       </Router>
      );
    }
    

    And inside the routes:

    const component = () => {
      ...
      return (
        <Routes>
          <Route path="/" element={<Navigate to="/homepage" replace />} />
          <Route path="homepage" element={<StartPage />} />
          ...
          <Route path="*" element={<NotFound />} />
      );
    }
    

    I am think I am skiping something easy and short. but I cannot fin it. This is happening when I am updating to v6 of react and also this library to last version. After error, if I reaload the page, page works. Also, I am looking in the redux, the state of path doesnt change. Before yes.

    Thanks for your time.

    Kind regards.

    opened by JavierBeni 7
  • Support for MemoryHistory or HashHistory

    Support for MemoryHistory or HashHistory

    Hello, I saw your library a couple of days ago and it was just what I was looking for. It works perfectly with redux-toolkit and react-router-dom. However, I have a question regarding other history types. So far, you are supporting createBrowserHistory. I am trying to package my react app using electron-pack as a desktop application, and it's known that electron supports MemoryHistory and HashHistory but not BrowserHistory. I tried using MemoryHistory and HashHistory with redux-first-history but apparently neither work. Do you think there us a way to do it or will you at least support in future versions?

    Thank you

    opened by jKh98 7
  • No location change when using push from saga

    No location change when using push from saga

    Hi there,

    first of all thanks for providing this package!

    However, I have a small issue and I'm not sure if it my setup or anything else. Following your docs I want to dispatch a location change from a saga (use push action creator from redux-first-history if you need to dispatch location from saga or connected components.). I'm using react-router v6.

    # mysaga.ts
    import { push } from "redux-first-history"
    ...
    
    function* redirect() {
      yield put(push("/somewhere"))
    }
    
    function* watchSomething() {
      yield takeLatest(MyActionType.SOME_ACTION, redirect)
    }
    
    export function* mySaga() {
      yield all([
        fork(watchSomething)
      ])
    }
    

    The action is executed, but there is no redirect:

    image

    Why does it behave this way? Hope you can shed a light, thanks!

    Here is my store setup:

    const { createReduxHistory, routerMiddleware, routerReducer } =
      createReduxHistoryContext({
        history: createBrowserHistory(),
      })
    
    const sagaMiddleware = createSagaMiddleware()
    const initialState = window.INITIAL_REDUX_STATE
    
    export const store = createStore(
      combineReducers({
        authentication: authenticationReducer,
        employees: employeesReducer,
        layout: layoutReducer,
        router: routerReducer,
      }),
      initialState,
      composeWithDevTools(
        applyMiddleware(routerMiddleware),
        applyMiddleware(sagaMiddleware)
      )
    )
    
    sagaMiddleware.run(rootSaga)
    
    export const history = createReduxHistory(store)
    
    opened by dArignac 6
  • Issue in route if hash: null

    Issue in route if hash: null

    Hello. Good library a lot of thanks.

    I have one question i used library https://github.com/mjrussell/redux-auth-wrapper#readme

    i have some code.

    import { connectedReduxRedirect } from 'redux-auth-wrapper/history3/redirect';
    import { push } from 'redux-first-history';
    
    export const UserIsAuthenticated = connectedReduxRedirect({
      redirectPath: 'login',
      authenticatedSelector: (state) => !isEmpty(state.global.get('currentUser').toJS()),
      redirectAction: push,
      wrapperDisplayName: 'UserIsAuthenticated',
      allowRedirectBack: false,
    });
    

    but redirect to login route incorrect. I gettting loginnull instead login I debugging code and i noticed. image if hash: null then i have incorrect route. I checked if hash: undefined then all good. Could you help me. Maybe i something understand.

    opened by sergeu90 6
  • support

    support "navigate" from @reach-router?

    I couldn't find any example how to set this up with reach router. Can you give me a simple example how to apply the reachify history to the reach router?

    opened by bassplayerch 6
  • Cannot read properties of undefined (reading 'pathname')

    Cannot read properties of undefined (reading 'pathname')

    Hello, thank you for this repo! I was directed here based on your comment of using redux-first-history instead of connected-react-router. I wanted to ask, because I feel like I'm following your instructions properly, but I'm running into a strange error. Here is what I have. Everything is pretty much boilerplate from what's in the README:

    store.js (with @reduxjs/toolkit)

    import { combineReducers } from "redux";
    import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit";
    import { createHashHistory, createBrowserHistory } from "history";
    import { createReduxHistoryContext } from "redux-first-history";
    
    const { routerMiddleware, createReduxHistory, routerReducer } = createReduxHistoryContext({
      history: createHashHistory()
    });
    
    export const store = configureStore({
      reducer: combineReducers({
        router: routerReducer
      }),
      middleware: [...getDefaultMiddleware({
        serializableCheck: false
      }), routerMiddleware]
    });
    
    export const history = createReduxHistory(store);
    

    app.js (react-router v6)

    import React from "react";
    import { HistoryRouter } from "redux-first-history/rr6";
    import { Provider } from "react-redux";
    import AppRoutes from "Core/routes";
    import Nav from "./nav";
    import "./root.css";
    
    class Root extends React.Component {
      render() {
        const { store, history } = this.props;
        
        return (
          <React.Fragment>
            <Provider store={store}>
              <HistoryRouter history={history}>
                <Nav history={history}></Nav>
                <AppRoutes></AppRoutes>
              </HistoryRouter>
            </Provider>
          </React.Fragment>
        );
      }
    }
    
    export default Root;
    

    routes.jsx

    import React from "react";
    import { Routes, Route } from "react-router";
    import ROUTES from "Constants/routes";
    import loadable from "@loadable/component";
    
    // Load bundles asynchronously so that the initial render happens faster
    const Welcome = loadable(() =>
      import(/* webpackChunkName: "WelcomeChunk" */ "Pages/welcome/welcome")
    );
    const About = loadable(() =>
      import(/* webpackChunkName: "AboutChunk" */ "Pages/about/about")
    );
    
    class AppRoutes extends React.Component {
      render() {    
        return (
          <Routes>
            <Route path={ROUTES.WELCOME} element={<Welcome />}></Route>
            <Route path={ROUTES.ABOUT} element={<About />}></Route>        
          </Routes>
        );
      }
    }
    
    export default AppRoutes;
    
    

    welcome.jsx

    import React from "react";
    import ROUTES from "Constants/routes";
    import { Link } from "react-router-dom";
    
    class Welcome extends React.Component {
      render() {
        return (
          <React.Fragment>
            <section className="section">
              <div className="container">
                <h2 className="title is-2">Samples</h2>
                <div>
                  <Link to={ROUTES.ABOUT}>About page</Link> <br />
                </div>
              </div>
            </section>
          </React.Fragment>
        );
      }
    }
    
    export default Welcome;
    

    about.jsx

    import React from "react";
    
    class About extends React.Component {
      render() {
        return (
          <section className="section">
              <div className="container">
                  <h1 className="title is-1">About</h1>
              </div>          
          </section>
        );
      }
    }
    
    export default About;
    

    My app loads fine, but as soon as I try to navigate to another page I get this error Cannot read properties of undefined (reading 'pathname'). I can't figure out if this is an error in redux-first-history or somewhere else. This comment makes me feel like <HistoryRouter> needs to support something like this (but I'm not entirely sure).

    <HistoryRouter location={history.location} navigator={history}>
    

    Can you point me in the right direction?

    repro steps

    I made a small POC repo where this can be replicated https://github.com/reZach/react-router-v6-upgrade

    opened by reZach 5
  • Missing @types/reach__router dependencie when using RFH with React-router

    Missing @types/reach__router dependencie when using RFH with React-router

    Hi, Updating react-router from V5 to V6 I moved to redux-first-history because connected-react-router does not support react-router V6. I also updated history to v5 because it is the version used in react-router v6. But compiling I have the folowing issue with redux-first-history :

    node_modules/redux-first-history/build/es6/actions.d.ts(9,19): error TS2315: Type 'Location' is not generic.
    node_modules/redux-first-history/build/es6/create.d.ts(2,46): error TS7016: Could not find a declaration file for module '@reach/router'. '/opt/atlassian/pipelines/agent/build/code/node_modules/@reach/router/index.js' implicitly has an 'any' type.
      Try `npm i --save-dev @types/reach__router` if it exists or add a new declaration (.d.ts) file containing `declare module '@reach/router';`
    node_modules/redux-first-history/build/es6/reachify.d.ts(1,41): error TS7016: Could not find a declaration file for module '@reach/router'. '/opt/atlassian/pipelines/agent/build/code/node_modules/@reach/router/index.js' implicitly has an 'any' type.
      Try `npm i --save-dev @types/reach__router` if it exists or add a new declaration (.d.ts) file containing `declare module '@reach/router';` 
    

    I kinda find wierd that I would have to install types from another router to use RFH with react-router. But I probably missing something... On the other hand Location type used to be generic but isn't anymore.

    opened by theFreedomBanana 5
  • Problem with 'push' and 'replace' types

    Problem with 'push' and 'replace' types

    Seems like push and replace functions only accept location: LocationDescriptorObject<HistoryLocationState> as a parameter. In History interface they are overloaded, for example push function:

    push(path: Path, state?: HistoryLocationState): void;
    push(location: LocationDescriptorObject<HistoryLocationState>): void;
    

    And then it is declared like this:

    export declare const push: (...args: Parameters<History['push']>) => CallHistoryMethodAction<Parameters<History['push']>>;
    

    But when declaring function parameters like this, only the last overload is used, hence I can't just pass a path string to the function but only a location object.

    opened by isjaki 0
  • Uncaught Error: useRoutes() may be used only in the context of a <Router> component.

    Uncaught Error: useRoutes() may be used only in the context of a component.

    Hi,

    I am getting the error in the title. I can fix it by wrapping from the package with , but that's against the documentation and the provided example there.

    Can you please help me out, what could have I done wrong here?

    opened by red17electro 1
  • State not changed when routing change

    State not changed when routing change

    I have application.

    And when i change router - redux store does not change

    Example: https://codesandbox.io/s/crazy-darwin-s112t4

    I use redux-logger and there are no LOCATION_CHANGE messages in console

    opened by Tsyklop 0
  • History v5 types error + back and forward actions are not exported

    History v5 types error + back and forward actions are not exported

    • goBack and goForward methods are no longer exist in history v5 types. Build process is crashing
    • new back and forward actions are not exported from index.ts
    opened by MustonenMishka 6
  • basename for location.pathname support

    basename for location.pathname support

    In previous version of history package the basename was also used for making location.pathname relative to basename, see history v4 api

    For example with basename /foo/bar/id and url /foo/bar/id/baz the pathname will be /baz

    Then in the 5th version they removed basename support silently.

    I am seeing that you've added support for basename in v5.1.0

    So I am wondering are there any plans to expose relative pathname under router.location in redux store?

    opened by aliaksandr-yermalayeu 0
  • Support for react-router 6.4.0

    Support for react-router 6.4.0

    Hey team - was just wondering if there's any planned support for react-router v6.4.0?

    After attempting to migrate to their newer method of wiring up routes, it appears it requires a whole new provider to be used, which doesn't seem to require creating the history instance to provide it - I'm assuming it now does it internally. Not too sure what changes would be required within redux-first-router to support this new way of wiring up the router, but at present due to the internal abstraction of history within react-router's new API it doesn't seem to be possible to integrate it with redux-first-history.

    Any updates on this would be greatly appreciated 🙏

    opened by voodoocreation 8
Releases(v5.1.1)
  • v5.1.1(Sep 10, 2022)

  • v5.1.0(Sep 10, 2022)

    • Added support for basename
    import { createReduxHistoryContext } from "redux-first-history";
    import { createBrowserHistory } from 'history'; //v5
    
    const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 
      history: createBrowserHistory(),
      basename: '/app',
      //other options if needed 
    });
    
    Source code(tar.gz)
    Source code(zip)
  • v5.0.12(Jun 24, 2022)

  • v5.0.11(Jun 20, 2022)

  • v5.0.10(Jun 17, 2022)

  • v5.0.9(Apr 9, 2022)

  • v5.0.8(Dec 13, 2021)

  • v5.0.7(Dec 11, 2021)

    • restored internal rr6 support (react-router v6.1.1)

    rr6 support :

    import { HistoryRouter as Router } from "redux-first-history/rr6";
    import { Route, Routes, Navigate } from "react-router-dom";
    //...
    import { store, history } from "./store";
    //...
    
         <Router history={history}>
                     <Routes>
                       <Route path="/dashboard" element={<Dashboard />} />
                       <Route path="/" element={<Home />} />
                       <Route path="*" element={<Navigate to="/" />} />
                     </Routes>
         </Router>
    
    

    demo rr6 here: https://codesandbox.io/s/redux-first-history-demo-rr6-uccuw

    Source code(tar.gz)
    Source code(zip)
  • v5.0.6(Dec 10, 2021)

    • removed rr6 folder since is now merged into react-router 6.1.0 https://github.com/remix-run/react-router/releases/tag/v6.1.0

    rr6 support :

    import { Route, Routes, Navigate, HistoryRouter as Router } from "react-router-dom";
    import { store, history } from "./store";
    //...
         <Router history={history}>
                     <Routes>
                       <Route path="/dashboard" element={<Dashboard />} />
                       <Route path="/" element={<Home />} />
                       <Route path="*" element={<Navigate to="/" />} />
                     </Routes>
         </Router>
    
    
    Source code(tar.gz)
    Source code(zip)
  • v5.0.5(Dec 9, 2021)

  • v5.0.4(Dec 9, 2021)

  • v5.0.3(Nov 14, 2021)

  • v5.0.2(Nov 13, 2021)

  • v5.0.1(Nov 10, 2021)

  • v5.0.0(Nov 9, 2021)

    • rewritten in TS
    • add support for react-router v6 !
    • tests coverage 100% !

    rr6 support :

    import { HistoryRouter as Router } from "redux-first-history/rr6";
    import { Route, Routes, Navigate } from "react-router-dom";
    //...
    import { store, history } from "./store";
    //...
    
         <Router history={history}>
                     <Routes>
                       <Route path="/dashboard" element={<Dashboard />} />
                       <Route path="/" element={<Home />} />
                       <Route path="*" element={<Navigate to="/" />} />
                     </Routes>
         </Router>
    
    

    demo rr6 here: https://codesandbox.io/s/redux-first-history-demo-rr6-uccuw

    BREAKING CHANGES:

    • removed option "oldLocationChangePayload"
    Source code(tar.gz)
    Source code(zip)
  • v5.0.0-beta.2(Aug 16, 2021)

    • rewritten in TS
    • add support for react-router v6.0.0-beta.1
    import { HistoryRouter as Router } from "redux-first-history/rr6";
    import { Route, Routes, Navigate } from "react-router-dom";
    //...
    import { store, history } from "./store";
    //...
    
         <Router history={history}>
                     <Routes>
                       <Route path="/dashboard" element={<Dashboard />} />
                       <Route path="/" element={<Home />} />
                       <Route path="*" element={<Navigate to="/" />} />
                     </Routes>
         </Router>
    
    

    demo rr6 here: https://codesandbox.io/s/redux-first-history-demo-rr6-uccuw

    Source code(tar.gz)
    Source code(zip)
  • v5.0.0-beta.1(Aug 29, 2020)

    • support history v5.0.0
    • support react-router v6.0.0-alpha.1 https://github.com/ReactTraining/react-router/releases/tag/v6.0.0-alpha.1 (removed "listenObject" flag, it will autodetect rr6/history5.x

    BREAKING CHANGES:

    • removed oldLocationChangePayload flag
    import { createReduxHistoryContext, reachify } from "redux-first-history";
    import { createWouterHook } from "redux-first-history/wouter";
    import { createBrowserHistory } from "history";
    
    const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 
        history: createBrowserHistory(), 
     });
    
    export const history = createReduxHistory(store);
    export const reachHistory = reachify(history);
    export const wouterUseLocation = createWouterHook(history);
    
    Source code(tar.gz)
    Source code(zip)
  • v4.6.0-beta.1(Feb 2, 2020)

    • support history v5.0.0
    • support react-router v6.0.0 (add listenObject: true options ) https://github.com/ReactTraining/react-router/releases/tag/v6.0.0-alpha.1
    import { createReduxHistoryContext, reachify } from "redux-first-history";
    import { createWouterHook } from "redux-first-history/wouter";
    import { createBrowserHistory } from "history";
    
    const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 
        history: createBrowserHistory(), 
        listenObject: true, // support react-router v6.0
     });
    
    export const history = createReduxHistory(store);
    export const reachHistory = reachify(history);
    export const wouterUseLocation = createWouterHook(history);
    
    Source code(tar.gz)
    Source code(zip)
  • v4.5.0(Jan 24, 2020)

    • support imperatively navigate from @reach/routerimport { navigate } from '@reach/router'`

    usage:

    import { createBrowserHistory } from 'history';
    import { globalHistory } from '@reach/router';
    
    const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 
      history: createBrowserHistory(),
      //others options if needed 
      reachGlobalHistory: globalHistory 
    });
    
    Source code(tar.gz)
    Source code(zip)
  • v4.2.6(Jan 16, 2020)

  • v4.2.5(Nov 23, 2019)

    support batch options:
    a batch function for batching states updates with history updates. Prevent some "edge case" top-down updates on react : usage import { unstable_batchedUpdates } from 'react-dom'; batch = unstable_batchedUpdates

    Source code(tar.gz)
    Source code(zip)
  • v4.2.0(Nov 13, 2019)

  • v4.1.1(Oct 18, 2019)

  • v4.1.0(Oct 9, 2019)

  • v4.0.5(Aug 27, 2019)

  • v4.0.4(Jun 8, 2019)

  • v4.0.3(May 23, 2019)

  • v.4.0.1(May 22, 2019)

    +GA release ! (it should be stable ->https://github.com/salvoravida/redux-first-history/issues/10) +typescript index.d.ts added (thanks to https://github.com/salvoravida/redux-first-history/pull/3 and https://github.com/salvoravida/redux-first-history/pull/4) +support redux-immutable (thanks to https://github.com/salvoravida/redux-first-history/pull/7)

    Source code(tar.gz)
    Source code(zip)
  • v.4.0.0-alpha.6(Oct 1, 2018)

Owner
Salvatore Ravidà
senior software engineer / full remote
Salvatore Ravidà
Hash Route + History Route Additional based for React Route v6

Hash Route + History Route Additional based for React Route v6 Support Version Map React React Scripts Bear React Grid 18 5.0.1

Imagine 3 May 30, 2022
Redux bindings for React Router – keep your router state inside your Redux store

redux-router This project is experimental. For bindings for React Router 1.x see here In most cases, you don’t need any library to bridge Redux and Re

Andrew Clark 2.3k Dec 7, 2022
Render isomorphic React + React Router apps and components in Node

Render isomorphic React + React Router apps and components in Node

Sequence Media 3 Nov 1, 2022
named routes for react-router and your react application

react-router-namesake Example import { Switch } from "react-router"; import { BrowserRouter, Route, Link } from "react-router-dom"; import { Router as

Joe Hsu 6 Aug 12, 2021
Frontend of agro rent app built with React, Axios, React-router-dom v6 & Bootstrap

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: ya

Anuj Sharma 1 Dec 8, 2021
React app with TypeScript - React Router Dom

React Project with - React Router Dom My name is Alex Principe. I'm a Full stack developer who shares programming code with the community. This repo c

Alex Principe 2 Sep 20, 2022
You can found the concept of react hooks, local storage, conditional rendering and react-router-dom.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Tikaram Acharya 2 Jun 1, 2022
a more intuitive way of defining private, public and common routes for react applications using react-router-dom v6

auth-react-router is a wrapper over react-router-dom v6 that provides a simple API for configuring public, private and common routes (React suspense r

Pasecinic Nichita 12 Dec 3, 2022
Automatic breadcrumbs for React-Router

React Breadcrumbs React component use to generate a breadcrumb trail (compatible with React Router). Installation npm install --save react-breadcrumbs

Sven Anders Robbestad 409 Dec 9, 2022
Declarative router component for React.

React Router Component Version Compatibility >= 0.39.0 React v15,16 >= 0.32.0 React v15 >= 0.27.0 React 0.14 0.24 - 0.26.0 React 0.13 0.23 - 0.26.0 Re

Samuel Reed 871 Nov 29, 2022
React Router scroll management

react-router-scroll React Router scroll management. react-router-scroll is a React Router middleware that adds scroll management using scroll-behavior

Jimmy Jia 846 Dec 18, 2022
🔼 UI-Router for React

UI-Router provides extremely flexible, state based routing to the React ecosystem.

UI-Router 444 Dec 22, 2022
Easy Router for Effector with React bindings

effector-easy-router A declarative router for effector and react. It is inspired by react-router-dom and effector gates. Routes are independent from e

Kirill Kubryakov 10 Oct 7, 2022
React router that supports rendering of multiple independent (auxiliary) routes.

aux-router React router that supports rendering of multiple independent (auxiliary) routes. Install npm install --save aux-router Documentation AuxRou

Kamil Bugno 20 Oct 4, 2021
A small router library for React focusing on the Developer Experience

Crossroad A routing library for React with a familiar interface. It has some differences with React Router so you write cleaner code: The links are pl

Francisco Presencia 17 Dec 10, 2022
A simple and safe router for React and TypeScript.

A simple and safe router for React and TypeScript.

Mathieu Acthernoene 247 Dec 31, 2022
Code examples for our React Router 6 update video

About This Repository This repository belongs to my "React Router v6 Upgrade Guide" YouTube video. You can also learn all about React (incl. React Rou

Academind 45 Jan 1, 2023
Full page transitions with react-router.

react-tiger-transition Page transitions for react router dom. Animate your routes programmatically during navigation. Instead of defining the animatio

pedrobern 477 Dec 5, 2022
🗺️ Static route mapping for React Router

React Router Chart Create a single source map of truth for all routes in your react app and easily render in react-router Getting Started Install Incl

Emmanuel Ogbizi 5 Feb 10, 2022