使用 Redux-Router + React-Router 将基本 URL 添加到应用程序
Posted
技术标签:
【中文标题】使用 Redux-Router + React-Router 将基本 URL 添加到应用程序【英文标题】:Adding a base URL to an app using Redux-Router + React-Router 【发布时间】:2016-01-27 08:41:59 【问题描述】:我正在使用React-Router1.0.0-rc3 和Redux-Router1.0.0-beta3。
在使用 React-Router 时,您可以使用 useBasename
和 createHistory
来设置应用程序的基本 URL,以便您可以轻松编写在子目录中运行的应用程序。 Example:
而不是这个:
import createHistory from 'history';
let base = "/app_name/"
<Router history=browserHistory>
<Route path=base component=App></Route>
</Router>
<Link path=base + "some_path">some_path</Link>
你可以用useBasename
这样写:
import createHistory, useBasename from 'history';
const browserHistory = useBasename(createHistory)(
basename: "/app_name"
);
<Router history=browserHistory>
<Route path="/" component=App></Route>
</Router>
<Link path="/some_path">some_path</Link>
但是,在 Redux-Router 中,您需要将 createHistory
而不是 history
传递给 reducer:
const store = compose(
applyMiddleware(m1, m2, m3),
reduxReactRouter(
routes,
createHistory
),
devTools()
)(createStore)(reducer);
在这种情况下我们如何使用useBasename
?
【问题讨论】:
我不确定第二个示例(“您可以使用 useBasename 以这种方式编写”)的含义。它似乎正在使用“历史”模块(不是 React 的一部分)。此外,如果您已经在使用从 react-router 导入的“browserHistory”对象,则不能用“const browserHistory”定义覆盖它。如果我将其替换为“newBrowserHistory”,则会收到错误“TypeError: _history.useBasename is not a function”。所以老实说,我无法对这个例子做出正面或反面。 【参考方案1】:对于 react-router v2 或 v3 并使用 react-router-redux v4 而不是 redux-router,历史对象的设置将如下所示:
import createHistory from 'history'
import useRouterHistory from 'react-router'
import syncHistoryWithStore from 'react-router-redux'
const browserHistory = useRouterHistory(createHistory)(
basename: '<yourBaseUrl>'
)
const history = syncHistoryWithStore(browserHistory, store)
当没有额外的基本 URL 时,其余设置与往常一样。
【讨论】:
完美运行,推荐您使用最新的react-router
和react-router-redux
我没有使用 react-router-redux(只是普通的 react-router),但上面的代码对我有用,但省略了最后一行。
我无法让它与最新版本的历史记录一起使用:createHistory is not a function
。如果我const createHistory = require('history').createBrowserHistory;
,那么我的路线似乎与basename: '/'
不匹配。有什么想法吗?
我刚刚让它使用与react-router@2.8.1
相同的(旧)版本的history
工作:history@2.1.2
。如果有人让它与最新版本之一一起工作,(例如history@4.3.0
)请告诉我。
@DamianoBarbati 您不能仅仅因为它现在不适合您而否决这个答案。这是对原始问题的正确书面回答。请成熟地使用您的vote down 权限。【参考方案2】:
你可以创建一个包装useBasename
的函数:
const createHistoryWithBasename = (historyOptions) =>
return useBasename(createHistory)(
basename: '/app_name',
...historyOptions
)
并将其传递给compose
:
const store = compose(
applyMiddleware(m1, m2, m3),
reduxReactRouter(
routes,
createHistory: createHistoryWithBaseName
),
devTools()
)(createStore)(reducer);
【讨论】:
【参考方案3】:API 经常更改,所以这对我有用(我使用的是redux-simple-router
的2.0.3
版本)。我在单独的文件中定义了自定义历史记录:
import useRouterHistory from 'react-router'
import createHistory, useBasename from 'history'
import baseUrl from '../config'
const browserHistory = useRouterHistory(useBasename(createHistory))(
basename: "/appgen"
);
现在我需要初始化商店:
import syncHistory, routeReducer from 'redux-simple-router'
import browserHistory from '../misc/browserHistory'
const rootReducer = combineReducers(
// ...other reducers
routing: routeReducer
);
const reduxRouterMiddleware = syncHistory(browserHistory);
const finalCreateStore = compose(
// ...other middleware
applyMiddleware(reduxRouterMiddleware),
)(createStore);
const store = finalCreateStore(rootReducer, initialState);
最终,您需要将history
传递给Router
。
import browserHistory from './misc/browserHistory'
import routes from '../routes'
export default class Root extends Component
static propTypes =
history: PropTypes.object.isRequired
;
render()
return (
<Router history=browserHistory>
routes
</Router>
)
在我想出这个之前,我使用的是手动解决方案。我定义了我自己的 Link
组件和我自己的负责添加基本 URL 的 redux 操作。它可能对某人有用。
更新Link
组件:
import React, Component from 'react'
import Link as RouterLink from 'react-router'
import baseUrl from '../config'
export default class Link extends Component
render()
return <RouterLink ...this.props to=baseUrl + '/' + this.props.to />
自定义动作创建者:
import routeActions from 'redux-simple-router'
import baseUrl from '../config'
export function goTo(path)
return routeActions.push(baseUrl + '/' + path);
更新根路由:
import baseUrl from './config'
export default (
<Route component=App path=baseUrl>
//...nested routes
</Route>
);
请注意,这些自定义工具仅支持推送更新的路径,不支持位置描述符对象。
【讨论】:
你使用“browserHistory.push('/otherPage')”吗?如果是这样-您是否设置了其他东西以使其正常工作?我这样做时会丢失基本名称... 不。现在已经有一段时间了,但我想说正确的做法是调度goTo
操作,而不是手动使用低级 API。【参考方案4】:
迭戈五世答案的变体对我有用(不知道我在做什么):
import createHistory from 'history'
import useRouterHistory from 'react-router'
...
const _browserHistory = useRouterHistory(createHistory)(
basename: '/yourbase'
)
const store = createStore(_browserHistory, api, window.__data)
const history = syncHistoryWithStore(_browserHistory, store)
我正在替换:
//const _browserHistory = useScroll(() => browserHistory)()
【讨论】:
以上是关于使用 Redux-Router + React-Router 将基本 URL 添加到应用程序的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Redux 获取新数据以响应 React Router 更改?