如何让react app有条不紊地收听redux store?

时间:2017-06-20 18:33:08

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

我有一个针对大学管理的React应用程序。

以下是我的路由器:

<Route path="selecting/" component={SelectUniversity}>
    <Route path="myUniversity" component={MyUniversity} />
    <Route path="studentdetails" component={AddStudentDetails} />
    <Route path="payment" component={Payment} />
</Route>

流程==&gt; MyUniversity ==&gt; AddStudentDetails ==&gt;付款 因此,一切都按预期工作 所有三个组件 MyUniversity,AddStudentDetails,Payment 都可以使用 redux store

进行扩展

MyUniversity的 mapStateToProps 如下

function mapStateToProps(state) {
  const { results } = state.results

  const studentData = state.results.studentData
  return {
    results,
    studentData,
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ ...Actions, ...studentActions }, dispatch)
}

涉及许多商店变量,这是出于示例目的 同样,为其他两个组件分别使用mapstaetoprops和mapdispatchtoprop。

现在的要求是(出于某些不可避免的原因): -

如果用户直接登录myuniversity页面,其ID如下所示: - http://mywebsite.com/myuniversity/9999, 我需要获取与9999相关的数据(已经获得)并执行相同的流程。

我更新的路由器

<Route path="selecting/" component={SelectUniversity}>
    <Route path="myUniversity" component={MyUniversity} />
    <Route path="myUniversity/:unidetails" component={MyUniversity} />
    <Route path="studentdetails" component={AddStudentDetails} />
    <Route path="payment" component={Payment} />
</Route>

获取数据后,如何更新redux存储,以便现有流程按预期工作。

我知道一旦我们从ajax调用中获取数据,我可以调度尽可能多的动作,但就像我说的那样,三个组件中的每一个都涉及15-20个不同的状态变量。因此,在每个组件负载上激发这么多调度程序似乎不是一种可扩展的方法。

方法2 所以我提出了另一种方法: - 1.定义一个新的减速器。 2.获取数据后,整个ajax结果将以所需的格式存储在状态中。 3.现在转到三个组件中每个组件的mapstatetoprops,并在每个道具级别添加条件,无论是从透视减速器还是当前减速器获取数据。

例如: - 假设我添加了另一个名为 universitydetails 的减速器 然后我的mapstatetoprops看起来像这样

const { results } = state.results || state.universitydetails

const studentData = state.results.studentData || state.universitydetails.studentData

return {
        results,
        studentData,
      }

然后再次,在每个道具级别添加条件(假设我在三个组件的每一个中使用15-20个不同的状态变量)

方法3 : - 在myuniversity load上添加redux-saga和dispatch动作,并根据它生成其他动作 但这不是通用的。 Incase,我想为其他东西添加simliar功能,例如宿舍然后我再次需要为这个主机添加sagas并且需要在初始加载时调度动作。

我认为最好的方法(如果我错了,请纠正我): - 定义一个新的reducer并以某种方式让我的组件监听这个reducer(就像方法2但没有弄清楚代码)所以如果我想添加另一个功能,如hostelselector,我只需要更新我的新减速机结构,让我的组件听取这个新的减速机

我被困在某种程度上 有任何建议如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

好的,我想我明白了你的申请流程是什么以及我的想法。

您可以创建一个简化器,它只响应一个名为&#39; SET_SOURCE&#39;的操作。它会将当前源的名称放在应从中提取数据的位置。理想情况下,它应该是您的数据将被保留的reducer / object的名称。

之后,您必须为每个源创建一个reducer。每个消息来源都将对自己负责,并且他们不会互相交流。这意味着,当您的ajax调用完成并且您必须将数据保存在商店内部(也就是触发操作)时,您将触发操作以触发您想要的减速器。

你的减速器的结构可能是这样的:

=> myUniversity
      => currentSource
      => sources
            => uniDetails
            => hostel etc.

您可以使用combineReducers函数

实现此类结构
// myUniversityReducer.js
import uniDetails from 'uniDetailsReducer'
import hostel from 'hostelReducer'
import currentSource from 'currentSourceReducer'

const sources = combineReducers({hostel, uniDetails})
const myUniversity = combineReducers({currentSource, sources})

export myUniversity

mapStateToProps内,您可以选择当前来源:

function mapDispatchToProps = (state) => {
  const currentSource = selectCurrentSource(state) // currentSource = 'uniDetails' => name of the reducer
  const dataFromSource = selectDataFromSources(state, currentSource) // dataFromSource = state[currentSource] => object inside uniDetails

  // ... if here you need to manipulate data because the structure of every
  // source is different, you can have your function that will do that based on the source name

  return { ...dataFromSource }
}

这是我的想法,但我可能有机会错过某些东西或者我误解了某些情景