Добавление базового URL-адреса в приложение с помощью Redux-Router + React-Router
Я использую React-Router 1.0.0-rc3 вместе с Redux-Router 1.0. 0-бета3.
При использовании React-Router вы можете использовать useBasename
с createHistory
, чтобы установить базовый URL-адрес приложения, чтобы вы могли легко написать приложение, которое выполняется внутри подкаталога. Пример:
Вместо этого:
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
в редуктор:
const store = compose(
applyMiddleware(m1, m2, m3),
reduxReactRouter({
routes,
createHistory
}),
devTools()
)(createStore)(reducer);
Как мы можем использовать useBasename
в этом случае?
Ответы
Ответ 1
Для реактивного маршрутизатора 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.
Ответ 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 меняется очень часто, так что это сработало для меня (я использую 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"
});
Теперь мне нужно инициализировать хранилище:
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
и мое собственное действие redux, которое отвечало за добавление базового URL-адреса. Это может быть полезно для кого-то.
Обновлен компонент 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>
);
Обратите внимание, что эти настраиваемые инструменты поддерживают только толкание обновленных путей, а не объект дескриптора местоположения.
Ответ 4
Вариант ответа Диего 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)
Я заменял:
//const _browserHistory = useScroll(() => browserHistory)()