【问题标题】:Adding a base URL to an app using Redux-Router + React-Router使用 Redux-Router + React-Router 将基本 URL 添加到应用程序
【发布时间】:2016-01-27 08:41:59
【问题描述】:

我正在使用React-Router1.0.0-rc3 和Redux-Router1.0.0-beta3。

在使用 React-Router 时,您可以使用 useBasenamecreateHistory 来设置应用程序的基本 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”。所以老实说,我无法对这个例子做出正面或反面。

标签: javascript reactjs redux react-router


【解决方案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-routerreact-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-router2.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)()
    

    【讨论】:

      猜你喜欢
      • 2020-09-20
      • 2023-04-03
      • 2016-04-19
      • 2017-01-16
      • 2020-07-05
      • 2016-09-06
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      相关资源
      最近更新 更多