All Projects → salvoravida → Redux First History

salvoravida / Redux First History

Licence: mit
🎉 Redux First History - Redux history binding support react-router - @reach/router - wouter

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Redux First History

cra-redux-boilerplate
⚛️🔨create-react-app application with redux and another cool libraries to make your life easier.
Stars: ✭ 15 (-90.8%)
Mutual labels:  router, react-router, react-redux
Dva Starter
完美使用 dva react react-router,最好用的ssr脚手架,服务器渲染最佳实践
Stars: ✭ 60 (-63.19%)
Mutual labels:  react-router, react-redux
Simple Universal React Redux
The simplest possible Async Universal React & Redux Boilerplate app, that works on both Mac and Windows
Stars: ✭ 58 (-64.42%)
Mutual labels:  react-router, react-redux
React Demo Gather
react demo合集,有自己写的,也有在学习过程中觉得很好的demo收集的,持续更新中
Stars: ✭ 97 (-40.49%)
Mutual labels:  react-router, react-redux
Slack Patron
Log and view all Slack messages.
Stars: ✭ 157 (-3.68%)
Mutual labels:  react-router, react-redux
Piwik React Router
Piwik analytics component for react-router
Stars: ✭ 53 (-67.48%)
Mutual labels:  history, react-router
Dva React Worms
dva新手综合教程
Stars: ✭ 70 (-57.06%)
Mutual labels:  react-router, react-redux
Create React App Redux
React Router, Redux, Redux Thunk & Create React App boilerplate
Stars: ✭ 885 (+442.94%)
Mutual labels:  react-router, react-redux
Cwg React Starter
Pre-configured and Ready to use React Starter App. To save time in settings things up for new project. Almost everything needed is already configured. Just clone and start developing without wasting time in doing same stuffs for every project. (#codewithghazi)
Stars: ✭ 122 (-25.15%)
Mutual labels:  react-router, react-redux
React Redux Graphql Apollo Bootstrap Webpack Starter
react js + redux + graphQL + Apollo + react router + hot reload + devTools + bootstrap + webpack starter
Stars: ✭ 127 (-22.09%)
Mutual labels:  router, react-router
Create React Server
Server & middleware for React + Router + Redux with Server Side Rendering
Stars: ✭ 139 (-14.72%)
Mutual labels:  react-router, react-redux
Redux Saga Router
A router for Redux Saga
Stars: ✭ 153 (-6.13%)
Mutual labels:  router, history
React Antd Admin Template
一个基于React+Antd的后台管理模版,在线预览https://nlrx-wjc.github.io/react-antd-admin-template/
Stars: ✭ 1,022 (+526.99%)
Mutual labels:  react-router, react-redux
Egg React Typescript Boilerplate
Egg React TypeScript Server Side Render (SSR) / Client Side Render (CSR)
Stars: ✭ 56 (-65.64%)
Mutual labels:  react-router, react-redux
React Redux Antdesign Webpack Starter
react + redux + ant design + react-router 4 + webpack 4 starter
Stars: ✭ 44 (-73.01%)
Mutual labels:  router, react-router
Route
原生 js 实现的轻量级路由,且页面跳转间有缓存功能。
Stars: ✭ 68 (-58.28%)
Mutual labels:  router, history
V2 Universal Js Hmr Ssr React Redux
⚡ (V2) Universal JS - Server Side Rendering, Code Splitting and Hot Module Reloading ⚡
Stars: ✭ 147 (-9.82%)
Mutual labels:  react-router, react-redux
Soundcloud Redux
SoundCloud API client with React • Redux • Redux-Saga
Stars: ✭ 681 (+317.79%)
Mutual labels:  react-router, react-redux
Todo React Redux
Todo app with Create-React-App • React-Redux • Firebase • OAuth
Stars: ✭ 942 (+477.91%)
Mutual labels:  react-router, react-redux
React Login
A client side implementation of authentication using react.js for my blog on medium. This is the second part of my previous blog on how to implement scalable node.js server.
Stars: ✭ 105 (-35.58%)
Mutual labels:  react-router, react-redux

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.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].