├── .babelrc ├── .gitignore ├── .npmignore ├── README.md ├── lib └── index.js ├── package.json └── src └── index.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": ["transform-object-rest-spread"] 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | .DS_Store 3 | node_modules 4 | TODO 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | TODO 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-router-redux-params 2 | 3 | Provides extra methods for [react-router-redux](https://github.com/reactjs/react-router-redux) which store [react-router](https://github.com/reactjs/react-router) route params in addition to history location object. 4 | 5 | You won't need this if you're only accessing route params inside your components, react-router already provides params as a prop. This is meant for usage outside component tree, for example with [refire](https://github.com/hoppula/refire). 6 | 7 | **NOTE** This hasn't been tested with [redux-devtools](https://github.com/gaearon/redux-devtools), breakage might ensue. 8 | 9 | ## Usage 10 | 11 | ```js 12 | import React from 'react' 13 | import ReactDOM from 'react-dom' 14 | import { createStore, combineReducers, applyMiddleware } from 'redux' 15 | import { Provider } from 'react-redux' 16 | import { Router, Route, browserHistory } from 'react-router' 17 | import { syncHistory, syncParams, routeParamsReducer } from 'react-router-redux-params' 18 | import reducers from '/reducers' 19 | 20 | const routes = ( 21 | 22 | 23 | ) 24 | 25 | const reducer = combineReducers(Object.assign({}, reducers, { 26 | routing: routeParamsReducer 27 | })) 28 | 29 | // Sync dispatched route actions to the history 30 | const createStoreWithMiddleware = applyMiddleware( 31 | syncHistory(browserHistory) 32 | )(createStore) 33 | 34 | const store = createStoreWithMiddleware(reducer) 35 | // syncParams also accepts custom action creator as fourth parameter, see src/index.js for more info 36 | syncParams(store, routes, browserHistory) 37 | 38 | ReactDOM.render( 39 | 40 | 41 | 42 | {routes} 43 | 44 | 45 | , 46 | document.getElementById('mount') 47 | ) 48 | ``` 49 | 50 | ## License 51 | 52 | MIT 53 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.UPDATE_LOCATION_WITH_PARAMS = undefined; 7 | 8 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 9 | 10 | var _reactRouterRedux = require('react-router-redux'); 11 | 12 | Object.keys(_reactRouterRedux).forEach(function (key) { 13 | if (key === "default" || key === "__esModule") return; 14 | Object.defineProperty(exports, key, { 15 | enumerable: true, 16 | get: function get() { 17 | return _reactRouterRedux[key]; 18 | } 19 | }); 20 | }); 21 | exports.syncParams = syncParams; 22 | exports.routeParamsReducer = routeParamsReducer; 23 | 24 | var _matchRoutes = require('react-router/lib/matchRoutes'); 25 | 26 | var _matchRoutes2 = _interopRequireDefault(_matchRoutes); 27 | 28 | var _reactRouter = require('react-router'); 29 | 30 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 31 | 32 | var UPDATE_LOCATION_WITH_PARAMS = exports.UPDATE_LOCATION_WITH_PARAMS = "@@router/UPDATE_LOCATION_WITH_PARAMS"; 33 | 34 | 35 | var initialState = { 36 | location: undefined, 37 | params: {} 38 | 39 | // default action creator, you can also use your own by passing it as fourth parameter to syncParams, 40 | // just remember to use a matching reducer 41 | };function updateLocationWithParams(location, state) { 42 | return { 43 | type: UPDATE_LOCATION_WITH_PARAMS, 44 | payload: { 45 | location: location, 46 | params: state ? state.params : {} 47 | } 48 | }; 49 | } 50 | 51 | var updateParams = function updateParams(store, routesArray, actionCreator) { 52 | return function (location) { 53 | (0, _matchRoutes2.default)(routesArray, location, function (error, state) { 54 | if (!error) { 55 | store.dispatch(actionCreator(location, state)); 56 | } 57 | }); 58 | }; 59 | }; 60 | 61 | function syncParams(store, routes, history) { 62 | var actionCreator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : updateLocationWithParams; 63 | 64 | var routesArray = (0, _reactRouter.createRoutes)(routes); 65 | var updateDispatcher = updateParams(store, routesArray, actionCreator); 66 | 67 | // dispatch the initial params manually 68 | updateDispatcher(history.getCurrentLocation()); 69 | 70 | return history.listen(updateDispatcher); 71 | } 72 | 73 | function routeParamsReducer() { 74 | var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; 75 | var _ref = arguments[1]; 76 | var type = _ref.type, 77 | payload = _ref.payload; 78 | 79 | if (type === UPDATE_LOCATION_WITH_PARAMS) { 80 | return _extends({}, state, { 81 | location: payload.location, 82 | params: payload.params 83 | }); 84 | } 85 | return state; 86 | } 87 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-router-redux-params", 3 | "version": "2.0.0", 4 | "description": "Extends react-router-redux to store react-router params to Redux", 5 | "main": "lib/index.js", 6 | "keywords": [ 7 | "redux", 8 | "react-router", 9 | "react-router-redux", 10 | "routing", 11 | "refire" 12 | ], 13 | "scripts": { 14 | "build": "mkdir -p lib && babel ./src/index.js --out-file ./lib/index.js", 15 | "watch": "mkdir -p lib && babel ./src/index.js --watch --out-file ./lib/index.js" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/hoppula/react-router-redux-params" 20 | }, 21 | "dependencies": { 22 | "react-router-redux": "3.0.0" 23 | }, 24 | "peerDependencies": { 25 | "react-router": "^3.0.0" 26 | }, 27 | "author": "Lari Hoppula", 28 | "license": "MIT", 29 | "devDependencies": { 30 | "babel-cli": "^6.6.5", 31 | "babel-core": "^6.6.5", 32 | "babel-plugin-transform-object-rest-spread": "^6.6.5", 33 | "babel-preset-es2015": "^6.6.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import matchRoutes from 'react-router/lib/matchRoutes' 2 | import { createRoutes } from 'react-router' 3 | export const UPDATE_LOCATION_WITH_PARAMS = "@@router/UPDATE_LOCATION_WITH_PARAMS" 4 | export * from 'react-router-redux' 5 | 6 | const initialState = { 7 | location: undefined, 8 | params: {} 9 | } 10 | 11 | // default action creator, you can also use your own by passing it as fourth parameter to syncParams, 12 | // just remember to use a matching reducer 13 | function updateLocationWithParams(location, state) { 14 | return { 15 | type: UPDATE_LOCATION_WITH_PARAMS, 16 | payload: { 17 | location: location, 18 | params: state ? state.params : {} 19 | } 20 | } 21 | } 22 | 23 | const updateParams = (store, routesArray, actionCreator) => location => { 24 | matchRoutes(routesArray, location, (error, state) => { 25 | if (!error) { 26 | store.dispatch(actionCreator(location, state)) 27 | } 28 | }) 29 | } 30 | 31 | export function syncParams(store, routes, history, actionCreator = updateLocationWithParams) { 32 | const routesArray = createRoutes(routes) 33 | const updateDispatcher = updateParams(store, routesArray, actionCreator) 34 | 35 | // dispatch the initial params manually 36 | updateDispatcher(history.getCurrentLocation()) 37 | 38 | return history.listen(updateDispatcher) 39 | } 40 | 41 | export function routeParamsReducer(state = initialState, { type, payload }) { 42 | if (type === UPDATE_LOCATION_WITH_PARAMS) { 43 | return { 44 | ...state, 45 | location: payload.location, 46 | params: payload.params 47 | } 48 | } 49 | return state 50 | } 51 | --------------------------------------------------------------------------------