Skip to content

Commit

Permalink
Support for basename and some other props for Router
Browse files Browse the repository at this point in the history
  • Loading branch information
llh911001 committed Sep 16, 2017
1 parent 933748b commit 8fed715
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 29 deletions.
4 changes: 3 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,9 @@ This is very useful for large apps.

> Mirror uses [[email protected]](https://github.com/ReactTraining/react-router), so if you're from react-router 2.x/3.x, you should checkout the [Migrating from v2/v3 to v4 Guide](https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/migrating.md).
This is an enhanced `Router` component from [react-router](https://github.com/ReactTraining/react-router/tree/master/packages/react-router). The `history` and `store` is automatically passed to `Router`, all you have to do is declare your routes.
This is an enhanced `Router` component from [react-router](https://github.com/ReactTraining/react-router/tree/master/packages/react-router). The `history` and `store` is automatically passed to `Router`, all you have to do is declare your routes. But if you like, you can also create your own `history` object and pass it as a prop to `Router` component.

What about props like [`basename`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/BrowserRouter.md#basename-string) or [`getUserConfirmation`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/BrowserRouter.md#getuserconfirmation-func)? Well, Mirror's `Router` handles them all! For a complete list of props `Router` takes, check out [`BrowserRouter`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/BrowserRouter.md), [`HashRouter`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.md) and [`MemoryRouter`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/MemoryRouter.md).

The following components from `react-router` are also exported by Mirror:

Expand Down
4 changes: 3 additions & 1 deletion docs/zh/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,9 @@ render()

> Mirror 使用的是 [[email protected]](https://github.com/ReactTraining/react-router),如果你有 react-router 2.x/3.x 的经验,那么你应该仔细阅读一下 react-router 官方的[迁移指南](https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/migrating.md)
Mirror 的 `Router` 组件是加强版的 [react-router](https://github.com/ReactTraining/react-router/tree/master/packages/react-router)`Router`。所加强的地方在于,`Redux store``history` 都自动处理好了,不需要你去做关联,也不需要你去创建 `history` 对象,你只需要关心自己的业务逻辑,定义路由即可。
Mirror 的 `Router` 组件是加强版的 [react-router](https://github.com/ReactTraining/react-router/tree/master/packages/react-router)`Router`。所加强的地方在于,`Redux store``history` 都自动处理好了,不需要你去做关联,也不需要你去创建 `history` 对象,你只需要关心自己的业务逻辑,定义路由即可。当然,如果你想自己创建一个 `history` 对象,然后通过 prop 传递给 `Router` 组件,也是没有任何问题的。

[`basename`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/BrowserRouter.md#basename-string) 以及 [`getUserConfirmation`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/BrowserRouter.md#getuserconfirmation-func) 等 props 呢?不用担心,Mirror 的 `Router` 全都能处理它们。你可以查看 [`BrowserRouter`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/BrowserRouter.md)[`HashRouter`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.md)[`MemoryRouter`](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/MemoryRouter.md) 的文档获取更多信息。

因为 Mirror 没有将 `Router` 用到的 `history` 暴露出去,如果你需要手动更新 location,那么你可以使用 `actions.routing` 上的方法。

Expand Down
4 changes: 2 additions & 2 deletions examples/simple-router/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import mirror, {render, Router} from 'mirrorx'
import App from './App'

mirror.defaults({
historyMode: 'browser'
historyMode: 'hash'
})

render(
<Router>
<Router basename="/test" hashType="hashbang">
<App/>
</Router>
, document.getElementById('root'))
8 changes: 3 additions & 5 deletions src/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@ export default function createMiddleware() {

return next => action => {

const result = next(action)

let effectResult
let result = next(action)

if (typeof effects[action.type] === 'function') {
effectResult = effects[action.type](action.data, getState)
result = effects[action.type](action.data, getState)
}

hooks.forEach(hook => hook(action, getState))

return effectResult || result
return result
}
}
}
22 changes: 13 additions & 9 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { options } from './defaults'
import { dispatch } from './middleware'
import { actions } from './actions'

let history
export let history = null

export default function Router({ history = getHistory(), children }) {
export default function Router({ history: _history, children, ...others }) {

// Add `push`, `replace`, `go`, `goForward` and `goBack` methods to actions.routing,
// when called, will dispatch the crresponding action provided by react-router-redux.
Expand All @@ -22,9 +22,17 @@ export default function Router({ history = getHistory(), children }) {
return memo
}, {})

// Support for `basename` etc props for Router,
// see https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/BrowserRouter.md
if (!_history) {
_history = createHistory(others)
}

history = _history

// ConnectedRouter will use the store from Provider automatically
return (
<ConnectedRouter history={history}>
<ConnectedRouter history={_history}>
{children}
</ConnectedRouter>
)
Expand All @@ -35,11 +43,7 @@ Router.propTypes = {
history: PropTypes.object
}

export function getHistory() {

if (history) {
return history
}
function createHistory(props) {

const { historyMode } = options

Expand All @@ -49,7 +53,7 @@ export function getHistory() {
memory: createMemoryHistory,
}

history = historyModes[historyMode]()
history = historyModes[historyMode](props)

return history
}
21 changes: 21 additions & 0 deletions src/routerMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @credit react-router-redux
* @see https://github.com/ReactTraining/react-router/blob/master/packages/react-router-redux/modules/middleware.js
*
* This is the routerMiddleware from react-router-redux, but to use
* the global `history` object instead of the passed one.
*/

import { CALL_HISTORY_METHOD } from 'react-router-redux'
import { history } from './router'

export default function routerMiddleware() {
return () => next => action => {
if (action.type !== CALL_HISTORY_METHOD) {
return next(action)
}

const { payload: { method, args } } = action
history[method](...args)
}
}
6 changes: 3 additions & 3 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import {
combineReducers,
compose
} from 'redux'
import { routerMiddleware, routerReducer } from 'react-router-redux'
import { routerReducer } from 'react-router-redux'

import createMiddleware from './middleware'
import { getHistory } from './router'
import routerMiddleware from './routerMiddleware'

export let store

export function createStore(models, reducers, initialState, middlewares = []) {

const middleware = applyMiddleware(
routerMiddleware(getHistory()),
routerMiddleware(),
...middlewares,
createMiddleware()
)
Expand Down
32 changes: 24 additions & 8 deletions test/router.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import mirror, { actions, render, Router } from 'index'
import { history } from 'router'

beforeEach(() => {
jest.resetModules()
Expand Down Expand Up @@ -27,11 +29,7 @@ describe('the enhanced Router', () => {


it('should pass history to Router', () => {
const mirror = require('index')
const { render, Router } = mirror
const { getHistory } = require('router')

const history = getHistory()
const container = document.createElement('div')

render(
Expand All @@ -45,8 +43,6 @@ describe('the enhanced Router', () => {
})

it('should add navigation methods of history object to actions.routing', () => {
const mirror = require('index')
const { actions, render, Router } = mirror

const container = document.createElement('div')

Expand All @@ -70,8 +66,6 @@ describe('the enhanced Router', () => {
})

it('should change history when call methods in actions.routing', () => {
const mirror = require('index')
const { actions, render, Router } = mirror

const container = document.createElement('div')

Expand All @@ -92,4 +86,26 @@ describe('the enhanced Router', () => {

expect(rootContext.router.route.match.isExact).toBe(false)
})

it('should be ok if pass an history object', () => {

const createHashHistory = require('history/createHashHistory').default
const _history = createHashHistory()

const container = document.createElement('div')

render(
<Router history={_history}>
<ContextChecker/>
</Router>,
container
)

expect(rootContext.router.history).toBe(_history)

expect(rootContext.router.route.match.isExact).toBe(true)
actions.routing.push('/new')
expect(rootContext.router.route.match.isExact).toBe(false)
})

})

0 comments on commit 8fed715

Please sign in to comment.