web-dev-qa-db-ja.com

Redux-Router + React-Routerを使用してアプリにベースURLを追加する

React-Router 1.0.0-rc3を Redux-Router 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-Routerでは、createHistoryではなくhistoryをレデューサーに渡す必要があります。

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

この場合、useBasenameをどのように使用できますか?

15
chibicode

React-router v2またはv3で、redux-routerの代わりに react-router-redux v4を使用する場合、履歴オブジェクトの設定は次のようになります。

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がない場合は通常どおりです。

13
Diego V

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

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

最終的には、historyRouterに渡す必要があります。

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

これを思いつく前に、私はmanualソリューションを使用していました。独自の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>
);

これらのカスタムツールは、更新されたパスのプッシュのみをサポートし、ロケーション記述子オブジェクトはサポートしないことに注意してください。

1
tobik