使用Redux路由器+React路由器向应用程序添加基本URL

Adding a base URL to an app using Redux-Router + React-Router

本文关键字:路由器 添加 URL Redux +React 使用 应用程序      更新时间:2023-09-26

我正在使用React路由器1.0.0-rc3和Redux路由器1.0.0-beta3。

使用React Router时,您可以使用useBasenamecreateHistory来设置应用程序的基本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路由器中,您需要将createHistory而不是history传递给reducer:

const store = compose(
  applyMiddleware(m1, m2, m3),
  reduxReactRouter({
    routes,
    createHistory
  }),
  devTools()
)(createStore)(reducer);

在这种情况下,我们如何使用useBasename

对于react路由器v2或v3,并且使用react路由器redux v4而不是redux路由器,历史对象的设置将如下所示:

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时,其余的设置与往常一样。

您可以创建一个包装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);

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>
);

请注意,这些自定义工具只支持推送更新的路径,而不支持位置描述符对象

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)

我正在替换:

//const _browserHistory = useScroll(() => browserHistory)()