javascript 使用 Redux-Router + React-Router 向应用程序添加基本 URL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33376414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding a base URL to an app using Redux-Router + React-Router
提问by chibicode
I'm using React-Router1.0.0-rc3 together with Redux-Router1.0.0-beta3.
我正在使用React-Router1.0.0-rc3 和Redux-Router1.0.0-beta3。
When using React-Router, you can use useBasename
with createHistory
to set the base URL for an app, so that you can easily write an app that runs inside a subdirectory. Example:
使用 React-Router 时,您可以使用useBasename
withcreateHistory
来设置应用程序的基本 URL,以便您可以轻松编写在子目录中运行的应用程序。示例:
Instead of this:
取而代之的是:
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>
You can write in this way using useBasename
:
您可以使用以下方式编写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>
However, in Redux-Router, you need to pass createHistory
instead of history
to a reducer:
但是,在 Redux-Router 中,您需要传递createHistory
而不是传递history
给减速器:
const store = compose(
applyMiddleware(m1, m2, m3),
reduxReactRouter({
routes,
createHistory
}),
devTools()
)(createStore)(reducer);
How can we use useBasename
in this case?
useBasename
在这种情况下我们如何使用?
回答by Diego V
For react-router v2 or v3 and using react-router-reduxv4 instead of redux-router, the setup of the history object will look like this:
对于 react-router v2 或 v3 并使用react-router-reduxv4 而不是 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)
The rest of the setup is as usual when there is no extra base URL.
当没有额外的基本 URL 时,其余的设置与往常一样。
回答by chibicode
You can create a function that wraps useBasename
:
您可以创建一个包装函数useBasename
:
const createHistoryWithBasename = (historyOptions) => {
return useBasename(createHistory)({
basename: '/app_name',
...historyOptions
})
}
And pass it to compose
:
并将其传递给compose
:
const store = compose(
applyMiddleware(m1, m2, m3),
reduxReactRouter({
routes,
createHistory: createHistoryWithBaseName
}),
devTools()
)(createStore)(reducer);
回答by tobik
The API changes very often so this is what worked for me (I'm using the 2.0.3
version of redux-simple-router
). I have defined the custom history in a separate file:
API 经常更改,所以这对我有用(我正在使用 的2.0.3
版本redux-simple-router
)。我在单独的文件中定义了自定义历史记录:
import { useRouterHistory } from 'react-router'
import { createHistory, useBasename } from 'history'
import { baseUrl } from '../config'
const browserHistory = useRouterHistory(useBasename(createHistory))({
basename: "/appgen"
});
Now I need to initialize the store:
现在我需要初始化商店:
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);
Eventually, you need to pass the history
to the Router
.
最终,您需要将 传递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>
)
}
}
Before I came up with this, I was using a manualsolution. I defined my own Link
component and my own redux action that were responsible for prepending the base URL. It might be useful for someone.
在我想出这个之前,我使用的是手动解决方案。我定义了我自己的Link
组件和我自己的 redux 操作,它们负责在基本 URL 之前添加。它可能对某人有用。
Updated Link
component:
更新的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} />
}
}
Custom action creator:
自定义动作创建者:
import { routeActions } from 'redux-simple-router'
import { baseUrl } from '../config'
export function goTo(path) {
return routeActions.push(baseUrl + '/' + path);
}
Updated root route:
更新根路由:
import { baseUrl } from './config'
export default (
<Route component={App} path={baseUrl}>
//...nested routes
</Route>
);
Note that these custom tools only support pushing updated paths, not the location descriptor object.
请注意,这些自定义工具仅支持推送更新的路径,而不支持位置描述符对象。
回答by Ashley Aitken
A variant of Diego V's answer that worked for me (without knowing what I was doing):
对我有用的 Diego V 答案的一个变体(不知道我在做什么):
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)
I was replacing:
我正在更换:
//const _browserHistory = useScroll(() => browserHistory)()