Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@lagunovsky/redux-react-router

lagunovsky156.8kMIT4.4.1TypeScript support: included

A Redux binding for React Router v6

react, redux, react-redux, react-router, react-router-redux, connected-react-router

readme

License TypeScript Tests workflow

Redux React Router

A Redux binding for React Router

Main features

  • Synchronize router state with redux store through uni-directional flow (i.e. history -> store -> router -> components).
  • Supports React Router v7 and History v5
  • Supports functional component hot reloading while preserving state.
  • Dispatching of history methods (push, replace, go, back, forward) 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.
  • TypeScript

Installation

Redux React Router requires React 16.8, React Redux 6.0, React Router 6.0 or later.

npm install --save @lagunovsky/redux-react-router
yarn add @lagunovsky/redux-react-router

Usage

Examples

Note: the history object provided to reducer, middleware, and component must be the same history object.

@reduxjs/toolkit

`typescript jsx import { createRouterMiddleware, createRouterReducerMapObject, push, ReduxRouter } from '@lagunovsky/redux-react-router' import { configureStore } from '@reduxjs/toolkit' import { createBrowserHistory } from 'history' import React from 'react' import { createRoot } from 'react-dom/client' import { Provider, useDispatch } from 'react-redux' import { Route, Routes } from 'react-router' import { NavLink } from 'react-router-dom'

const history = createBrowserHistory() const routerMiddleware = createRouterMiddleware(history)

const store = configureStore({ reducer: createRouterReducerMapObject(history), middleware: (getDefaultMiddleware) => getDefaultMiddleware().prepend(routerMiddleware), })

function Content() { const dispatch = useDispatch()

const onClickHandler = () => { const action = push(Date.now().toString()) dispatch(action) }

return ( <> <NavLink to={'/'} children={'Home'}/> <button type={'button'} onClick={onClickHandler} children={'Rand'}/> </> ) }

function App() { return ( <Provider store={store}> <ReduxRouter history={history}> <Routes> <Route path={'*'} element={<Content/>}/> </Routes> </ReduxRouter> </Provider> ) }


#### `redux.createStore` and custom selector

```typescript jsx
import { createRouterMiddleware, createRouterReducer, push, ReduxRouter, ReduxRouterSelector } from '@lagunovsky/redux-react-router'
import { createBrowserHistory } from 'history'
import React from 'react'
import { createRoot } from 'react-dom/client'
import { Provider, useDispatch } from 'react-redux'
import { Route, Routes } from 'react-router'
import { NavLink } from 'react-router-dom'
import { applyMiddleware, combineReducers, compose, createStore } from 'redux'

const history = createBrowserHistory()
const routerMiddleware = createRouterMiddleware(history)

const rootReducer = combineReducers({ navigator: createRouterReducer(history) })

const store = createStore(rootReducer, compose(applyMiddleware(routerMiddleware)))
type State = ReturnType<typeof store.getState>

const routerSelector: ReduxRouterSelector<State> = (state) => state.navigator

function App() {
  return (
    <Provider store={store}>
      <ReduxRouter history={history} routerSelector={routerSelector}>
        <Routes>
          <Route path={'*'} element={<div/>}/>
        </Routes>
      </ReduxRouter>
    </Provider>
  )
}

API

Types

`typescript jsx type ReduxRouterProps = { history: History basename?: string children?: React.ReactNode routerSelector?: ReduxRouterSelector }


```typescript jsx
type ReduxRouterState = {
  location: history.Location
  action: history.Action
}

Constants

`typescript jsx const ROUTER_REDUCER_MAP_KEY = 'router' const ROUTER_CALL_HISTORY_METHOD = '@@router/CALL_HISTORY_METHOD' const ROUTER_ON_LOCATION_CHANGED = '@@router/ON_LOCATION_CHANGED'


#### `createRouterMiddleware(history: History) => Middleware`

A middleware you can apply to your Redux store to capture dispatched actions created by the action creators. 
It will redirect those actions to the provided history instance.

#### `createRouterReducerMapObject(history: History) => {router: Reducer<ReduxRouterState>}`

Creates a reducer map object that stores location updates from history.

#### `createRouterReducer(history: History) => Reducer<ReduxRouterState>`

Creates a reducer function that stores location updates from history.
Note: If you create a reducer with a key other than `ROUTER_REDUCER_MAP_KEY`, 
you must add a selector `(state: State) => ReduxRouterState` to your `<ReduxRouter/>` as `routerSelector` prop.

#### `reduxRouterSelector(state: State): ReduxRouterState`

Selector that returns location updates from history.

### Action creators

Same as [history methods](https://github.com/remix-run/history/blob/dev/docs/navigation.md)

- `push`
- `replace`
- `go` 
- `back`
- `forward`

By default, history methods calls in middleware are wrapped in a `queueMicrotask`. If you want to avoid it, please use the following methods:

- `pushStraight` 
- `replaceStraight` 
- `goStraight` 
- `backStraight` 
- `forwardStraight`

## Migrate from Connected React Router

```diff
- import { connectRouter } from 'connected-react-router'
+ import { createRouterReducer } from '@lagunovsky/redux-react-router'

- export const routerReducer = connectRouter(history)
+ export const routerReducer = createRouterReducer(history)
- import { routerMiddleware } from 'connected-react-router'
+ import { createRouterMiddleware } from '@lagunovsky/redux-react-router'

- export const routerMiddleware = routerMiddleware(history)
+ export const routerMiddleware = createRouterMiddleware(history)
- import { ConnectedRouter } from 'connected-react-router'
+ import { ReduxRouter } from '@lagunovsky/redux-react-router'

- <ConnectedRouter history={history} />
+ <ReduxRouter history={history} />
- import { RouterState } from 'connected-react-router'
+ import { ReduxRouterState } from '@lagunovsky/redux-react-router'

changelog

Changelog

4.2.2

  • readme update

4.2.0

Minor Changes

  • improved compatibility with @reduxjs/toolkit
  • useEffect usage fix

4.1.0

Minor Changes

  • history call as microtask by default

4.0.0

Major Changes

  • removed enableTimeTravelling prop, time travel is always available
  • removed store prop, store from the context is used

Bug Fixes

  • fixed synchronization of store and history. #9 (055fd62)