【问题标题】:How to split routes to different files with Redux and React-router?如何使用 Redux 和 React-router 将路由拆分到不同的文件?
【发布时间】:2016-12-14 23:16:02
【问题描述】:

我的应用程序中有很多路由。每个都有一个 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},
    ];
}

这甚至比第一个使用窗口作为一种廉价的方法来摆脱它似乎更糟糕。

任何想法如何正确分割路线?

【问题讨论】:

  • 您是否出于任何特定原因避免connect 路由组件并在component(Will|Did)Mount 中获取数据? github.com/ReactTraining/react-router/blob/v3.0.0/docs/guides/…
  • 是的,对于简单的组件,我使用 componentWillMount,但由于某些组件需要复杂的数据获取(缓存等),因此将路径放入(更高级别)对我来说更有意义。此外,路由的组件充当其他组件的容器,将数据获取拆分到许多内部组件会使事情变得更难理解,而且无论如何,在这个应用程序中,如果没有整个数据树,页面将无法运行。

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


【解决方案1】:

一种可能的解决方案是采用与react-routerbrowserHistoryhashHistory 相同的方法,即创建一个商店模块并从那里导出您的商店实例。

这可能会或可能不会根据您的代码结构工作,但基本上您将拥有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))
}

【讨论】:

    猜你喜欢
    • 2016-09-15
    • 2018-04-27
    • 2020-08-13
    • 2016-09-02
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    相关资源
    最近更新 更多