Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@lagunovsky/redux-react-router
Advanced tools
A Redux binding for React Router
push
, replace
, go
, back
, forward
) works for both redux-thunk
and redux-saga.react-redux
's connect
.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
Note: the history
object provided to reducer, middleware, and component must be the same history
object.
@reduxjs/toolkit
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 selectorimport { 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>
)
}
type ReduxRouterProps = {
history: History
basename?: string
children?: React.ReactNode
routerSelector?: ReduxRouterSelector
}
type ReduxRouterState = {
location: history.Location
action: history.Action
}
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.
Same as history methods
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
- 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'
FAQs
A Redux binding for React Router v6
We found that @lagunovsky/redux-react-router demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.