Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add pattern match #1

Merged
merged 12 commits into from
Aug 20, 2016
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ install:
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
addons:
firefox: "latest"
92 changes: 62 additions & 30 deletions README-ja.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# router-redux [![Build Status](https://travis-ci.org/subuta/router-redux.svg?branch=master)](https://travis-ci.org/subuta/router-redux) [![Coverage Status](https://coveralls.io/repos/github/subuta/router-redux/badge.svg?branch=master)](https://coveralls.io/github/subuta/router-redux?branch=master)
View framework agnostic router for redux :)
this is [react-router-redux](https://github.com/reactjs/react-router-redux) for your vdom-based project.
This is [react-router-redux](https://github.com/reactjs/react-router-redux) for your vdom-based project.

- `virtual-dom`系のライブラリを利用した開発フローを簡単にします。
- [virtual-dom](https://github.com/Matt-Esch/virtual-dom)と使ったり
Expand All @@ -17,14 +17,11 @@ npm install router-redux --save
まず、`routerReducer`をあなたの`reducer`に`routing`をキーとして渡す必要があります。

```javascript
// in reducers/index.js
// In reducers/index.js
import {combineReducers} from 'redux';
import {routerReducer} from 'router-redux';

import counter from './counter.js'; // 自分で書いたやつ

const rootReducer = combineReducers({
counter,
routing: routerReducer // ココ
});

Expand All @@ -35,7 +32,7 @@ export default rootReducer;
`routerCreator`から返却された`router`をexportしておいてください。

```javascript
// in example/store.js
// In example/store.js
import routerCreator, {routerMiddleware} from 'lib/index.js';

import reducer from './reducers/index.js';
Expand All @@ -61,33 +58,34 @@ import {

// もし初回ルーティング時のエラーを検知したいのであれば、まずonErrorを登録してください。
router.onError(({state, dispatch}) => {
const currentPath = getCurrent(state); // will extract currentPath from state(like '/')
// you can navigate user to error page or call any other redux action.
const currentPath = getCurrent(state).path; // statからcurrentPathを取得します。
// ユーザをエラーページへ遷移させるか、任意のreduxアクションを呼び出すことができます。
dispatch(push('/error'));
});

// ユーザがpath(/)に遷移した時に呼ばれます。
router.onEnter('/', ({state}, cb) => {
console.log('loading ...');
console.log('[top]loading ...', state);
setTimeout(() => {
console.log('enter in top');
// user's navigation action will blocked untill `cb` called.
// `cb`が呼び出されるまで、ユーザのページ遷移はブロックされます。
console.log('[top]timer fired');
cb();
// if you call `cb` with falsy value or Error object,
// router-redux will emit router's onError. and stop routing to path(/).
// cb(new Error('some error in top'));
// `cb`をfalsyな値もしくはErrorオブジェクトを引数として呼び出した場合
// router-reduxはrouteのonErrorを呼び出し、path(/)への遷移を中断します。
// cb(new Error('[top]thrown error'));
}, 1000);
});

// ユーザがpath(/)から別のpathに遷移する時に呼ばれます。
router.onLeave('/', (state) => {
console.log('leave from top');
console.log('[top]leave');
});
```

## Documentation

基本的なAPIのアイデアは [react-router-redux](https://github.com/reactjs/react-router-redux) を参考にしてます。ありがとうございます!
- 基本的なAPIのアイデアは [react-router-redux](https://github.com/reactjs/react-router-redux) を参考にしてます。thanks!
- 変更を加えた[object-assign](https://github.com/sindresorhus/object-assign)をライブラリサイズを減らす目的で含んでいます。thanks!

### `routerMiddleware`
Redux向けのrouter-reduxのmiddlewareです。
Expand Down Expand Up @@ -115,10 +113,7 @@ Redux向けのrouter-reduxのreducerです。
import {combineReducers} from 'redux';
import {routerReducer} from 'router-redux';

import counter from './counter.js'; // 自分で書いてるやつ

const rootReducer = combineReducers({
counter,
routing: routerReducer // ココ
});

Expand All @@ -135,6 +130,8 @@ export default rootReducer;
上記の`routerCreator`から作られます。これを利用して、独自のhandlerをrouterに定義する事ができます。

#### `router.onEnter(path, handler)`
- `path`には`/foo/:id`のような`path parameter`を含む事が出来ます。
- もし`path parameter`を指定した場合、`route-redux`は`route`オブジェクトの`route`と`params`プロパティを更新します。(詳細は`selectors`セクションを参照)
- `handler({state, dispatch}, [callback])`
- ユーザがpushState/popStateもしくはURLバーなどからの直接の遷移によって`path`に来た時に呼ばれます。
- handlerは`callback`関数が呼ばれるまで処理をブロックします。
Expand All @@ -143,16 +140,50 @@ export default rootReducer;
`router-redux`側で`router.onError`を呼び出し、遷移をキャンセルします。
(これは認証失敗や、サーバエラーが発生した場合に便利です。)
- もし`callback`関数を省略した場合は、onEnter関数内の結果はページ遷移に影響を及ぼしません。(非同期になるイメージ)
- もし`/`から`/foo/1`に遷移した場合は、`onEnter`に渡される`state.routing`は以下のようになります。

| key | value |
|:-----------------------|:-------------------------------|
| current | 現在のroute (`/`) |
| next | これから遷移するroute (`/foo/1`) |
| last | 直前のroute |

#### `router.onLeave(path, handler)`
- `handler({state, dispatch})`
- ユーザがpushState/popStateに寄って、`path`から去った時に呼ばれます。
- もし`/`から`/foo/1`に遷移した場合は、`onLeave`に渡される`state.routing`は以下のようになります。

| key | value |
|:-----------------------|:-----------------|
| current | 現在のroute (`/`) |
| next | `null` |
| last | 直前のroute |

#### `router.onError(handler)`
- `handler({state, dispatch})`
- routeErrorが`router.onEnter`で発生した時に呼ばれます。
- 実際のrouteErrorは`getRouteError`セレクタを利用して取得できます。

### `match`
- `math({path, anotherPath})`
- この関数を使うことで、currentPath(location)がpathにmatchするかチェックする事ができます。
- もしpathが`path parameter`を含んでいる場合、matchはマッチしたパラメータをオブジェクトとして返却します。

```javascript
import {
getCurrent,
match
} from 'router-redux';

const currentPath = getCurrent(state) && getCurrent(state).path;

// もしcurrentPath = `/`の場合
match('/', currentPath) // `{}`を返却します。

// もしcurrentPath = `/foo/1`の場合
match('/foo/:id', currentPath) // `{id: 1}`を返却します。
```

### actions
- redux向けのアクションを作ります。このアクションを利用してstore.dispatchを呼び出す必要があります。

Expand All @@ -166,12 +197,21 @@ export default rootReducer;

### selectors
- stateから値を抽出します。これらのセレクタは [reselect](https://github.com/reactjs/reselect) などから呼ぶことを想定しています。
- `route`は以下のプロパティを持ちます。
- path(`String`): `/foo/1 // path`
- query(`String`): `sample=true // クエリパラメータ. クエリ文字列のparseをするためには、外部のライブラリ(https://github.com/ljharb/qs など)を利用してください。`
- params(`Object`): `{id: 1} // matchしたパラメータ(onEnterで宣言したもの)`
- route(`String`): `/foo/:id // matchしたroute(onEnterで宣言したもの)`


#### `getCurrent(state)`
- `現在のpath`を`state`から抽出します。
- `現在のroute`を`state`から抽出します。

#### `getLast(state)`
- `直前のpath`を`state`から抽出します。
- `直前のroute`を`state`から抽出します。

#### `getNext(state)`
- `これから遷移するroute`を`state`から抽出します。

#### `getRouteError(state)`
- `routeError`を`state`から抽出します。
Expand Down Expand Up @@ -207,17 +247,9 @@ jspm i
```
caddy

# open link.
# Open link.
open http://localhost:3000
```

## LICENSE
[MIT](https://opensource.org/licenses/MIT)

## TODO
- [x] add README.
- [x] publish to npm
- [x] add tests
- [ ] add better route name handling with these libraries
- [url-pattern](https://github.com/snd/url-pattern)
- [qs](https://github.com/ljharb/qs)