如何使用Redux和React-router将路由分割到不同的文件?

时间:2016-12-14 23:16:02

标签: javascript reactjs redux react-router react-redux

我的申请中有很多路线。每个都有一个onEnter方法,它从API加载数据并在商店中触发一个动作(thunk)。

const routeConfig = [
    {path: '/tutorial/:tutorialId', component: Tutorial, onEnter: tutorialEnter},
    {path: '/session/:sessionId', component: App, onEnter: sessionEnter},
    {path: '/session/:userId/:sessionId', component: App, onEnter: userSessionEnter},
    {path: '/template/:language/:sessionId', component: App, onEnter: templateEditEnter},
    {path: '/snippet/:language/:appType/:sessionId', component: App, onEnter: snippetEditEnter},
    {path: '/prepare/:sessionId', component: Library, onEnter: galleryPrepareEnter},
    {path: '/launch/:comboId', component: Launch, onEnter: launchEnter},
    ... more

];

const renderStore = () => {
    rootElement = document.getElementById('root')

    render(
        <MuiThemeProvider>
            <div className="root">
                <Provider store={store}>
                    <Router history={history} routes={routeConfig} onUpdate={onPageView}/>
                </Provider>
            </div>
        </MuiThemeProvider>,

        rootElement
    );
}

OnEnter方法的示例:

const launchEnter = (location) => {
    let {comboId} = location.params;

    store.dispatch(appActions.getComboDetails(comboId))
    store.dispatch(appActions.getBuildRequestsForCombo(comboId))
}

我想将路由和OnEnter脚本拆分成不同的文件。我可以创建一个方法,返回一个包含一些路由的数组但是如何访问商店?我有两个想法似乎有缺陷:

创意#1 - 包装商店。 LaunchRoutes.js:

export const getRoutes = (store) => {

    const launchEnter = (location) => {
        let {comboId} = location.params;

        store.dispatch(appActions.getComboDetails(comboId))
        store.dispatch(appActions.getBuildRequestsForCombo(comboId))
    }

    return [
        {path: '/launch/:comboId', component: Launch, onEnter: launchEnter},
    ];
}

将商店锁定在此关闭状态是不对的。

想法#2 - 通过全局

访问商店
const store = window.store;

const launchEnter = (location) => {
    let {comboId} = location.params;

    store.dispatch(appActions.getComboDetails(comboId))
    store.dispatch(appActions.getBuildRequestsForCombo(comboId))
}

export const getRoutes = (store) => {

    return [
        {path: '/launch/:comboId', component: Launch, onEnter: launchEnter},
    ];
}

这甚至比第一个使用窗口作为一种便宜的方法更糟糕。

如何正确分割路线?

1 个答案:

答案 0 :(得分:0)

一种可能的解决方案是使用react-routerbrowserHistoryhashHistory相同的路线,这将创建商店模块并从那里导出商店实例。< / p>

根据您的代码结构,这可能有效,也可能无效,但基本上您会有store.js

import { createStore } from 'redux'
import reducers from './reducers'

export default createStore(reducers)

然后,您可以在整个项目中导入store,无论您需要与其进行交互。

// index.js
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'

import store from './store'

render((
  <Provider store={store}>...</Provider>
), holder)

// launchEnter.js
import store from './store'

const launchEnter = (location) => {
  let {comboId} = location.params;
  store.dispatch(appActions.getComboDetails(comboId))
  store.dispatch(appActions.getBuildRequestsForCombo(comboId))
}