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

标签 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},
    ];
}

这甚至比第一个使用窗口作为廉价出路的想法更糟糕。

有什么想法可以正确分割路线吗?

最佳答案

一种可能的解决方案是采用与 react-router 相同的路线 browserHistoryhashHistory,这将创建一个商店模块并从那里导出您的商店实例。

根据您的代码结构,这可能有效,也可能无效,但本质上您将拥有一个 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))
}

关于javascript - 如何使用 Redux 和 React-router 将路由拆分到不同的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41153877/

相关文章:

javascript - 为什么 document.createElement ('canvas' ).getContext ('2d' )。 hasOwnProperty ('font' )返回 false?

javascript - 为什么Webpack要注入(inject)React

reactjs - 我如何从 laravel api 推送通知来 react native 应用程序?

angular - 在 Angular(typescript) 中使用 tassign 的 Redux 试图加入 state.array 和 action.array 但获取 state.array.join 不是一个函数?

javascript - react 函数不渲染任何东西

javascript - jQuery 用博客日期标题的跨度替换连字符

javascript - net::ERR_CONNECTION_REFUSED 在 Cordova 应用程序上

javascript - 如何在reactjs中停止重新渲染?

javascript - 如何使 @connect 装饰器与 redux-saga 一起工作?

javascript - 在函数内渲染组件 react