Skip to content
This repository was archived by the owner on Oct 26, 2018. It is now read-only.

Update README and add CHANGELOG #93

Merged
merged 1 commit into from
Dec 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changelog

All notable changes to this project will be documented in this file.

## [Unreleased]

* Update to the new history API (#89)

## [1.0.0] - 2015-12-07

### Breaking

* The `updatePath` action creator has been removed in favor of `pushPath` and `replacePath` (#38)
* We have added support for routing state (#38)
* Our actions are now [FSA compliant](https://github.com/acdlite/flux-standard-action) (#63)

### Other

* Redux DevTools should now work as expected (#73)
* As we no longer depend on `window.location`, `<base href="...">` should now work (#62)
* We've done lots of work on finding the right way to stop cycles, so hopefully we shouldn't have any unnecessary location or store updates (#50)
157 changes: 71 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,60 @@

# redux-simple-router

[![npm version](https://img.shields.io/npm/v/redux-simple-router.svg?style=flat-square)](https://www.npmjs.com/package/redux-simple-router)
[![npm downloads](https://img.shields.io/npm/dm/redux-simple-router.svg?style=flat-square)](https://www.npmjs.com/package/redux-simple-router)
[![npm version](https://img.shields.io/npm/v/redux-simple-router.svg?style=flat-square)](https://www.npmjs.com/package/redux-simple-router) [![npm downloads](https://img.shields.io/npm/dm/redux-simple-router.svg?style=flat-square)](https://www.npmjs.com/package/redux-simple-router)

*Let react-router do all the work.*
**Let react-router do all the work** :sparkles:

[Redux](https://github.com/rackt/redux) is cool.
[react-router](https://github.com/rackt/react-router) is neat. The
problem is that react-router manages an important piece
of your application state: the URL. If you are using redux, you want
your app state to fully represent your UI; if you snapshotted the app
state, you should be able to load it up later and see the same thing.
[Redux](https://github.com/rackt/redux) is awesome. [React Router](https://github.com/rackt/react-router) is cool. The problem is that react-router manages an important piece of your application state: the URL. If you are using redux, you want your app state to fully represent your UI; if you snapshotted the app state, you should be able to load it up later and see the same thing.

react-router automatically maps the current URL to a path down your
component tree, and continually does so with any URL changes. This is
very useful, but we really want to store this state in redux as well.
react-router does a great job of mapping the current URL to a component tree, and continually does so with any URL changes. This is very useful, but we really want to store this state in redux as well.

The entire state that we are interested in boils down to one thing:
the URL. This is an extremely simple library that just puts the URL in
redux state and keeps it in sync with any react-router changes.
Additionally, you can change the URL via redux and react-router will
change accordingly.
The entire state that we are interested in boils down to one thing: the URL. This is an extremely simple library that just puts the URL in redux state and keeps it in sync with any react-router changes. Additionally, you can change the URL via redux and react-router will change accordingly.

```js
npm install redux-simple-router
```
##### _What about redux-router?_
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should move all of this redux-router stuff to the bottom, and focus on the usage and API first and foremost. Might be @jlongster disagrees, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will essentially replace redux-router and that will live as its own standalone project. -- #80

based on the above, it seems like rackt is moving away from redux-router, so this section probably won't be around for much longer... but since many people are already using redux-router, it might a good idea to leave this for the time being

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe adding a migration guide or example would be a good idea

migrating from redux-router? use this commit as a reference


[redux-router](https://github.com/rackt/redux-router) is another project which solves the same problem. However, it's far more complex. Take a quick look at [the code for this library](https://github.com/jlongster/redux-simple-router/blob/master/src/index.js)—it's extremely minimal. redux-router is much bigger and more complex.

## Isn't there already redux-router?
That said, redux-router is a fine project and has features this doesn't provide. Use it if you like it better.

[redux-router](https://github.com/rackt/redux-router) is another
project which solves the same problem. However, it's far more complex.
Just look at this code: the whole thing is only 68 lines of JS.
redux-router is much bigger and more complex.
**Compared with redux-router:**

That said, redux-router is a fine project and has features this
doesn't provide. Use it if you like it better.
* Much smaller and simpler. You don't need to learn another library on top of everything else.
* We encourage direct access of react-router APIs. Need server-side rendering, or something else advanced? Just read react-router's docs.
* We only store current URL and state, whereas redux-router stores the entire location object from react-router.

The differences between this and redux-router:
## Documentation

* Much smaller and simpler. You don't need to learn another library on
top of everything else.
* We encourage direct access of react-router APIs. Need server-side
rendering, or something else advanced? Just read react-router's
docs.
* The piece of state is just a URL string, whereas redux-router stores
the full location object from react-router.
0. [Usage](#how-to-use)
- [Installation](#installation)
0. [Tutorial](#tutorial)
0. [Examples](#examples)
0. [API](#api)
- [`syncReduxAndRouter(history, store, selectRouterState?)`](#syncreduxandrouter)
- [`routeReducer`](#routereducer)
- [`UPDATE_PATH`](#update-path)
- [`pushPath(path, state, { avoidRouterUpdate = false } = {})`](#pushpath)
- [`replacePath(path, state, { avoidRouterUpdate = false } = {})`](#replacepath)
0. [See also](#see-also)

This only depends on the `history.listen` function from react-router
and the `store.getState` and `store.subscribe` functions from redux.
It should be very future-proof with any versions of either libraries.
### Usage

## Examples
The idea of this library is to use react-router's functionality exactly like its documentation tells you to. You can access all of its APIs in routing components. Additionally, you can use redux like you normally would, with a single app state and "connected" components. It's even possible for a single component to be both if needed.

There are examples in the `examples` directory:
[redux](https://github.com/rackt/redux) (`store.routing`) &nbsp;&harr;&nbsp; [**redux-simple-router**](https://github.com/jlongster/redux-simple-router) &nbsp;&harr;&nbsp; [history](https://github.com/rackt/history) (`history.location`) &nbsp;&harr;&nbsp; [react-router](https://github.com/rackt/react-router)

1. [basic](https://github.com/jlongster/redux-simple-router/blob/master/examples/basic)
We only store current URL and state, whereas redux-router stores the entire location object from react-router. You can read it, and also change it with an action.

## How to Use
#### Installation

The idea of this library is to use react-router's functionality exactly
like its documentation tells you to. You can access all of its APIs in
routing components. Additionally, you can use redux like you normally
would, with a single app state and "connected" components. It's even
possible for a single component to be both if needed.
The latest redux-simple-router package can be install via NPM:

This library provides a single point of synchronization: the
`routing.path` piece of state which is the current URL. You can read
it, and also change it with an action.
```js
npm install --save redux-simple-router
```

Here's some code:
### Tutorial

Let's take a look at a simple example.

```js
import React from 'react'
Expand Down Expand Up @@ -102,22 +87,17 @@ ReactDOM.render(
)
```

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 `updatePath` action creator that we provide:
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:

```js
import { updatePath } from 'redux-simple-router'
import { pushPath } from 'redux-simple-router'

function MyComponent({ dispatch }) {
return <Button onClick={() => dispatch(updatePath('/foo'))}/>;
return <Button onClick={() => dispatch(pushPath('/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_PATH` constant that we provide:

```js
import { UPDATE_PATH } from 'redux-simple-router'
Expand All @@ -130,39 +110,44 @@ function update(state, action) {
}
```

For more context, check out this [full example](https://github.com/freeqaz/redux-simple-router-example).
### Examples

* [examples/basic](https://github.com/jlongster/redux-simple-router/blob/master/examples/basic) - basic reference implementation

Examples from the community:

* [davezuko/react-redux-starter-kit](https://github.com/davezuko/react-redux-starter-kit) - popular redux starter kit
* **tip**: migrating from redux-router? use [this commit](https://github.com/davezuko/react-redux-starter-kit/commit/db66626ca8a02ecf030a3f7f5a669ac338fd5897) as a reference
* [freeqaz/redux-simple-router-example](https://github.com/freeqaz/redux-simple-router-example) - example implementation

_Have an example to add? Send us a PR!_

### API

#### `syncReduxAndRouter(history, store, selectRouterState?)`

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.

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.

## API
#### `routeReducer`

### `syncReduxAndRouter(history, store, selectRouterState?)`
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`.

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.
#### `UPDATE_PATH`

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.
An action type that you can listen for in your reducers to be notified of route updates.

### `routeReducer`
#### `pushPath(path, state, { avoidRouterUpdate = false } = {})`

A reducer function that keeps track of the router state. You need to
add this reducer to your app reducers when creating the store. **The
piece of state must be named `routing`** (unless you provide a custom
`selectRouterState` function).
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.

### `UPDATE_PATH`
You can optionally pass a state to this action creator to update the state of the current route.

An action type that you can listen for in your reducers.
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.

### `updatePath(path, noRouterUpdate)`
#### `replacePath(path, state, { avoidRouterUpdate = false } = {})`

An action creator that you can use to update the current URL. Just
pass it a string like `/foo/bar?param=5`.
An action creator that you can use to replace the current URL without updating the browser history.

The `noRouterUpdate`, if `true`, will stop react-router from reacting
to this and all future URL changes. Pass `false` to make it start
reacting again. 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.
The `state` and the `avoidRouterUpdate` parameters work just like `pushPath`.