Gathering detailed insights and metrics for redux-first-history
Gathering detailed insights and metrics for redux-first-history
Gathering detailed insights and metrics for redux-first-history
Gathering detailed insights and metrics for redux-first-history
npm install redux-first-history
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
450 Stars
124 Commits
34 Forks
8 Watching
4 Branches
11 Contributors
Updated on 07 Nov 2024
Minified
Minified + Gzipped
TypeScript (97.39%)
JavaScript (2.61%)
Cumulative downloads
Total Downloads
Last day
-15%
13,977
Compared to previous day
Last week
0.1%
71,776
Compared to previous week
Last month
40.6%
313,853
Compared to previous month
Last year
56.4%
2,662,387
Compared to previous year
28
Redux First History - Make Redux 100% SINGLE-AND-ONLY source of truth!
Redux history binding for
react-router
@reach/router
wouter
react-location
react-router
- @reach/router
- wouter
- react-location
in the same app! See Demo.Compatible with immer
- redux-immer
- redux-immutable
.
:tada: A smaller, faster, optionated, issue-free alternative to
connected-react-router
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 the redux store, others that take location from router context, and others from withRouter HOC.
This can generate sync issues, due to the fact that many components are updated at different times. 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 !
Use whatever you like. History will just work as it should.
1//react-router v5 - v6 2useLocation() === state.router.location 3 4//react-router v5 5this.props.history.location === state.router.location 6this.props.location === state.router.location 7withRouter.props.location === state.router.location 8 9//react-router v4 10this.context.router.history.location === state.router.location 11this.context.route.location === state.router.location 12 13//@reach/router 14this.props.location === state.router.location 15 16//wouter - pathname 17useLocation()[0] === state.router.location.pathname
Mix redux, redux-saga, react-router, @reach/router, wouter and react-location
without any synchronization issue!
Why? Because there is no synchronization at all! There is only one history: reduxHistory!
react-router v6: https://wvst19.csb.app/
react-router v5: https://wy5qw1125l.codesandbox.io/
LOCATION_CHANGE
and push actions (taken from RRR)Using npm:
$ npm install --save redux-first-history
Or yarn:
$ yarn add redux-first-history
store.js
1import { createStore, combineReducers, applyMiddleware } from "redux"; 2import { composeWithDevTools } from "redux-devtools-extension"; 3import { createReduxHistoryContext, reachify } from "redux-first-history"; 4import { createWouterHook } from "redux-first-history/wouter"; 5import { createBrowserHistory } from 'history'; 6 7const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 8 history: createBrowserHistory(), 9 //other options if needed 10}); 11 12export const store = createStore( 13 combineReducers({ 14 router: routerReducer 15 //... reducers //your reducers! 16 }), 17 composeWithDevTools( 18 applyMiddleware(routerMiddleware) 19 ) 20); 21 22export const history = createReduxHistory(store); 23//if you use @reach/router 24export const reachHistory = reachify(history); 25//if you use wouter 26export const wouterUseLocation = createWouterHook(history);
store.js (with @reduxjs/toolkit)
1import { combineReducers } from "redux"; 2import { configureStore } from "@reduxjs/toolkit"; 3import { createReduxHistoryContext } from "redux-first-history"; 4import { createBrowserHistory } from "history"; 5 6const { 7 createReduxHistory, 8 routerMiddleware, 9 routerReducer 10} = createReduxHistoryContext({ history: createBrowserHistory() }); 11 12export const store = configureStore({ 13 reducer: combineReducers({ 14 router: routerReducer 15 }), 16 middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(routerMiddleware), 17}); 18 19export const history = createReduxHistory(store);
app.js
1import React, { Component } from "react"; 2import { Provider, connect } from "react-redux"; 3import { Router } from "react-router-dom"; 4import { store, history } from "./store"; 5 6const App = () => ( 7 <Provider store={store}> 8 <Router history={history}> 9 //..... 10 </Router> 11 </Provider> 12 ); 13 14export default App;
app.js (react-router v6)
1import React, { Component } from "react"; 2import { Provider } from "react-redux"; 3import { HistoryRouter as Router } from "redux-first-history/rr6"; 4import { store, history } from "./store"; 5 6const App = () => ( 7 <Provider store={store}> 8 <Router history={history}> 9 //..... 10 </Router> 11 </Provider> 12 ); 13 14export default App;
saga.js (react-saga)
1import { put } from "redux-saga/effects"; 2import { push } from "redux-first-history"; 3 4function* randomFunction() { 5 //.... 6 yield put(push(YOUR_ROUTE_PATH)); 7 //.... 8}
slice.js (in a Thunk with @reduxjs/toolkit)
1import { push } from "redux-first-history"; 2 3export const RandomThunk = (dispatch) => { 4 //.... 5 dispatch(push(YOUR_ROUTE_PATH)); 6 //.... 7}
react-router-redux
or connected-react-router
(in this case you have only to replace the import!)1export const createReduxHistoryContext = ({ 2 history, 3 routerReducerKey = 'router', 4 reduxTravelling = false, 5 selectRouterState = null, 6 savePreviousLocations = 0, 7 batch = null, 8 reachGlobalHistory = null 9})
key | optional | description |
---|---|---|
history | no | The createBrowserHistory object - v4.x/v5.x |
routerReducerKey | yes | if you don't like router name for reducer. |
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 |
basename | no | support basename (history v5 fix) |
1import { createReduxHistoryContext, reachify } from "redux-first-history"; 2import { createBrowserHistory } from 'history'; 3import { globalHistory } from '@reach/router'; 4 5const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 6 history: createBrowserHistory(), 7 reachGlobalHistory: globalHistory, 8 //other options if needed 9});
1import { createReduxHistoryContext, reachify } from "redux-first-history"; 2import { createBrowserHistory } from 'history'; 3import { unstable_batchedUpdates } from 'react-dom'; 4 5const { createReduxHistory, routerMiddleware, routerReducer } = createReduxHistoryContext({ 6 history: createBrowserHistory(), 7 batch: unstable_batchedUpdates, 8 //other options if needed 9});
Let me know what do you think!
Enjoy it? Star this project! :D
See Contributors.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
5 existing vulnerabilities detected
Details
Reason
Found 4/23 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More@cdmbase/redux-data-router
**`redux-data-router`** is a clean-room spiritual successor to projects like **redux-first-history**.
@types/redux-first-router
TypeScript definitions for redux-first-router
react-router-redux
Ruthlessly simple bindings to keep react-router and redux in sync
connected-react-router
A Redux binding for React Router v4 and v5