redux-simple-router
Advanced tools
Comparing version 2.0.1 to 2.0.2
## HEAD | ||
## [2.0.1](https://github.com/jlongster/redux-simple-router/compare/1.0.2...2.0.2) | ||
* New API that uses middleware to trap history calls for a better | ||
unidirectional data flow. New docs and updates coming soon (#141) | ||
Versions 2.0.0 and 2.0.1 were test releases for the 2.* series. 2.0.2 is the first public release. | ||
**A whole new API, with many breaking changes:** | ||
* `syncReduxAndRouter` is gone. Instead, call `syncHistory` with just the `history` object, which returns a middleware that you need to apply. (#141) | ||
* If you use redux devtools, you need to call `middleware.listenForReplays(store)` on the middleware returned from `syncHistory`. Create the store first with the middleware, then call this function with the store. | ||
* Action creators are now contained in a single object called `routeActions`. `go`, `goBack`, and `goForward` action creators have been added. | ||
* `UPDATE_PATH` is now `UPDATE_LOCATION`. | ||
* The fully parsed [location object](https://github.com/rackt/history/blob/master/docs/Location.md) is now stored in the state instead of a URL string. To access the path, use `state.routing.location.pathname` instead of `state.routing.path`. | ||
## [1.0.2](https://github.com/jlongster/redux-simple-router/compare/1.0.1...1.0.2) | ||
@@ -8,0 +15,0 @@ |
'use strict'; | ||
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; }; | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -57,3 +59,3 @@ value: true | ||
return { location: location }; | ||
return _extends({}, state, { location: location }); | ||
} | ||
@@ -86,10 +88,5 @@ | ||
if (action.type !== TRANSITION || !connected) { | ||
next(action); | ||
return; | ||
return next(action); | ||
} | ||
// FIXME: Is it correct to swallow the TRANSITION action here and replace | ||
// it with UPDATE_LOCATION instead? We could also use the same type in | ||
// both places instead and just set the location on the action. | ||
var method = action.method; | ||
@@ -103,3 +100,3 @@ var arg = action.arg; | ||
middleware.syncHistoryToStore = function (store) { | ||
middleware.listenForReplays = function (store) { | ||
var selectRouterState = arguments.length <= 1 || arguments[1] === undefined ? SELECT_STATE : arguments[1]; | ||
@@ -106,0 +103,0 @@ |
{ | ||
"name": "redux-simple-router", | ||
"version": "2.0.1", | ||
"version": "2.0.2", | ||
"description": "Ruthlessly simple bindings to keep react-router and redux in sync", | ||
@@ -65,6 +65,9 @@ "main": "lib/index", | ||
"mocha": "^2.3.4", | ||
"react": "^0.14.3", | ||
"redux": "^3.0.4", | ||
"redux-devtools": "^2.1.5", | ||
"redux-devtools": "^3.0.0", | ||
"redux-devtools-dock-monitor": "^1.0.1", | ||
"redux-devtools-log-monitor": "^1.0.1", | ||
"webpack": "^1.12.9" | ||
} | ||
} |
@@ -50,7 +50,7 @@ # redux-simple-router | ||
import ReactDOM from 'react-dom' | ||
import { createStore, combineReducers } from 'redux' | ||
import { compose, createStore, combineReducers, applyMiddleware } from 'redux' | ||
import { Provider } from 'react-redux' | ||
import { Router, Route } from 'react-router' | ||
import { createHistory } from 'history' | ||
import { syncReduxAndRouter, routeReducer } from 'redux-simple-router' | ||
import { syncHistory, routeReducer } from 'redux-simple-router' | ||
import reducers from '<project-path>/reducers' | ||
@@ -61,7 +61,13 @@ | ||
})) | ||
const store = createStore(reducer) | ||
const history = createHistory() | ||
syncReduxAndRouter(history, store) | ||
// Sync dispatched route actions to the history | ||
const reduxRouterMiddleware = syncHistory(history) | ||
const createStoreWithMiddleware = applyMiddleware(reduxRouterMiddleware)(createStore) | ||
const store = createStoreWithMiddleware(reducer) | ||
// Sync store to history | ||
reduxRouterMiddleware.syncHistoryToStore(store) | ||
ReactDOM.render( | ||
@@ -80,20 +86,20 @@ <Provider store={store}> | ||
Now you can read from `state.routing.path` to get the URL. It's far more likely that you want to change the URL more often, however. You can use the `pushPath` action creator that we provide: | ||
Now you can read from `state.routing.location.pathname` to get the URL. It's far more likely that you want to change the URL more often, however. You can use the `push` action creator that we provide: | ||
```js | ||
import { pushPath } from 'redux-simple-router' | ||
import { routeActions } from 'redux-simple-router' | ||
function MyComponent({ dispatch }) { | ||
return <Button onClick={() => dispatch(pushPath('/foo'))}/>; | ||
return <Button onClick={() => dispatch(routeActions.push('/foo'))}/>; | ||
} | ||
``` | ||
This will change the state, which will trigger a change in react-router. Additionally, if you want to respond to the path update action, just handle the `UPDATE_PATH` constant that we provide: | ||
This will change the state, which will trigger a change in react-router. Additionally, if you want to respond to the path update action, just handle the `UPDATE_LOCATION` constant that we provide: | ||
```js | ||
import { UPDATE_PATH } from 'redux-simple-router' | ||
import { UPDATE_LOCATION } from 'redux-simple-router' | ||
function update(state, action) { | ||
switch(action.type) { | ||
case UPDATE_PATH: | ||
case UPDATE_LOCATION: | ||
// do something here | ||
@@ -116,2 +122,3 @@ } | ||
* [bdefore/universal-redux](https://github.com/bdefore/universal-redux) - npm package for universally rendered redux applications | ||
* [yangli1990/react-redux-isomorphic](https://github.com/yangli1990/Isomorphic-Universal-React-Template) - boilerplate for universal redux and redux-simple-router | ||
@@ -122,28 +129,36 @@ _Have an example to add? Send us a PR!_ | ||
#### `syncReduxAndRouter(history, store, selectRouterState?)` | ||
**This API is for an unreleased version. To view docs for 1.0.2, [click here](https://github.com/rackt/redux-simple-router/tree/1.0.2#api)** | ||
Call this with a react-router and a redux store instance to install hooks that always keep both of them in sync. When one changes, so will the other. | ||
#### `syncHistory(history: History) => ReduxMiddleware` | ||
Call this to create a middleware that can be applied with Redux's `applyMiddleware` to allow actions to call history methods. The middleware will look for route actions created by `push`, `replace`, etc. and applies them to the history. | ||
#### `ReduxMiddleware.syncHistoryToStore(store: ReduxStore, selectRouterState?: function)` | ||
Call this on the middleware returned from `syncHistory` to start the syncing process between the history and store instance. | ||
Supply an optional function `selectRouterState` to customize where to find the router state on your app state. It defaults to `state => state.routing`, so you would install the reducer under the name "routing". Feel free to change this to whatever you like. | ||
#### `ReduxMiddleware.unsubscribe()` | ||
Call this on the middleware returned from `syncHistory` to stop the syncing process set up by `syncHistoryToStore`. | ||
#### `routeReducer` | ||
A reducer function that keeps track of the router state. You must to add this reducer to your app reducers when creating the store. If you do not provide a custom `selectRouterState` function, the piece of state must be named `routing`. | ||
A reducer function that keeps track of the router state. You must to add this reducer to your app reducers when creating the store. | ||
#### `UPDATE_PATH` | ||
#### `UPDATE_LOCATION` | ||
An action type that you can listen for in your reducers to be notified of route updates. | ||
#### `pushPath(path, state, { avoidRouterUpdate = false } = {})` | ||
#### `routeActions` | ||
An action creator that you can use to update the current URL and update the browser history. Just pass it a string like `/foo/bar?param=5` as the `path` argument. | ||
An object that contains all the actions creators you can use to manipulate history: | ||
You can optionally pass a state to this action creator to update the state of the current route. | ||
* `push(nextLocation: LocationDescriptor)` | ||
* `replace(nextLocation: LocationDescriptor)` | ||
* `go(n: number)` | ||
* `goForward()` | ||
* `goBack()` | ||
The `avoidRouterUpdate`, if `true`, will stop react-router from reacting to this URL change. This is useful if replaying snapshots while using the `forceRefresh` option of the browser history which forces full reloads. It's a rare edge case. | ||
#### `replacePath(path, state, { avoidRouterUpdate = false } = {})` | ||
An action creator that you can use to replace the current URL without updating the browser history. | ||
The `state` and the `avoidRouterUpdate` parameters work just like `pushPath`. | ||
A [location descriptor](https://github.com/rackt/history/blob/master/docs/Glossary.md#locationdescriptor) can be a descriptive object (see the link) or a normal URL string. The most common action is to push a new URL via `routeActions.push(...)`. These all directly call the analogous [history methods](https://github.com/rackt/history/blob/master/docs/GettingStarted.md#navigation). |
@@ -41,3 +41,3 @@ // Constants | ||
return { location } | ||
return { ...state, location } | ||
} | ||
@@ -66,10 +66,5 @@ | ||
if (action.type !== TRANSITION || !connected) { | ||
next(action) | ||
return | ||
return next(action) | ||
} | ||
// FIXME: Is it correct to swallow the TRANSITION action here and replace | ||
// it with UPDATE_LOCATION instead? We could also use the same type in | ||
// both places instead and just set the location on the action. | ||
const { method, arg } = action | ||
@@ -80,3 +75,3 @@ history[method](arg) | ||
middleware.syncHistoryToStore = | ||
middleware.listenForReplays = | ||
(store, selectRouterState = SELECT_STATE) => { | ||
@@ -83,0 +78,0 @@ const getRouterState = () => selectRouterState(store.getState()) |
302941
160
29
4862