减速器行为 [英] Reducer behavior

查看:46
本文介绍了减速器行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,当一个动作被调用时,所有的减速器都会响应.如果reducer 的switch case 语句中存在action,则执行.如果不是,则执行 case: default 保留现有状态.

As I understand it, when an action is called, all reducers respond. If action exists in the switch case statement of the reducer, it executes. If it doesn't, then the case: default executes which preserves the existing state.

当操作存在于 reducer 但它试图更新的特定属性不存在时,它似乎表现良好,因为没有什么可更新的.

When the action exists in the reducer but the particular property it's trying to update does not exist, it seems to behave OK as there's nothing to update.

例如,我有一个动作创建器,用于设置我的模态的 visible 属性.每个模态都有自己的Id.我的代码如下所示:

For example, I have an action creator that is used to set the visible property of my modals. Each modal has its own Id. My code looks like this:

export default (state = initialState, action) => {
   case types.SET_MODAL_IS_VISIBLE:
      return Object.assign({}, state,
         { modal22: action.value }
      )}

我在多个减速器中有 SET_MODAL_IS_VISIBLE 但如果 modal22 未在特定减速器中定义,则没有任何反应,也没有错误.

I have the SET_MODAL_IS_VISIBLE in multiple reducers but if modal22 is not defined in a particular reducer, nothing happens and no errors.

现在,我有一个抛出错误的场景.我有一个我构建的通用日期选择器组件,它可以用作单个独立的日期选择器,或者它可以链接到"另一个.如果我需要用户给我两个日期,例如,第二个场景很有用开始和结束日期.

Now, I have a scenario that is throwing an error. I have a general purpose date picker component that I built that can be used as a single and independent date picker OR it can be "linked to" another one. The second scenario is useful if I need the user to give me two dates e.g. start and end dates.

我还构建了一个功能,如果日期选择器与另一个日期选择器结合使用,当用户在第一个日期选择器中设置日期时,我会在第二个日期选择器中禁用该日期之前的所有日期,因为我没有希望用户无意中选择了一个早于开始日期的结束日期.

I also built a feature where if the date picker is coupled with another one, when the user sets the date in the first date picker, I disable all the dates prior to that date in the second date picker because I don't want the user to unintentionally select an end date that is prior to the start date.

我将我的日期选择器定义如下:

I define my date pickers as below:

const initialState = {
    datePickers: {
        "startDatePicker": {
            activeDate: "8/25/2017",
            disabledBefore: "",
            linkedTo: "endDatePicker"
         },
         "endDatePicker": {
            activeDate: "",
            disabledBefore: "8/25/2017" // This date is set when the user sets the active date in startDatePicker
            linkedTo: ""
       }
    }
}

这个场景有点有趣,因为我的 reducer 中一个属性的状态变化会触发另一个属性的状态变化.这并不难做到,我有一种方法可以控制何时进行更新.

This scenario is a bit interesting because a state change in one property in my reducer is triggering a state change in another. This is not difficult to do and I have a way of controlling when I do the update.

设置禁用日期的操作如下所示:

The action for setting disabled dates looks like below:

...
case types.SET_DISABLED_DATES:
    return Object.assign({}, state,
       datePickers: Object.assign({}, state.datePickers, {
          datePickers[action.datePickerId]: Object.assign({}, state.datePickers[action.datePickerId], {
             disabledBefore: action.value
          })
    })

请记住,即使日期选择器用作独立的,我也可以并且应该能够设置 disabledBefore.所以,我需要在每个减速器中使用我的 SET_DISABLED_DATES.

Please keep in mind that I can and should be able to set disabledBefore even if the date picker is used as an independent one. So, I need my SET_DISABLED_DATES in every reducer.

我遇到的问题是,每当我调用 SET_DISABLED_DATES 时,我都会在减速器中遇到错误,其中日期选择器被用作单个/独立的,因为其对的日期选择器 Id 是未在减速器中定义.

The problem I'm running into is that whenever I call SET_DISABLED_DATES, I get errors in reducers where the date picker is used as a single/independent one because the date picker Id for its pair is NOT defined in the reducer.

例如,在 projectsReducer 中,我可以使用日期选择器作为一对的一部分,这样 startDatePickerendDatePicker 都被定义,一切正常很好.

For example, in projectsReducer I may use the date picker as part of a pair so both startDatePicker and endDatePicker are defined and everything works fine.

但我可能在 tasksReducer 中使用单实例日期选择器,它也响应 SET_DISABLED_DATES 调用但它失败了,因为它找不到 endDatePicker.在这种情况下,tasksReducer 正在响应我在 projectsReducer 中设置 endDatePickerdisabledDates 属性的调用.

But I may be using a single instance date picker in the tasksReducer which also responds to the SET_DISABLED_DATES call but it fails because it cannot find the endDatePicker. In this scenario, the tasksReducer is responding to the call I made to set the disabledDates property of endDatePicker in projectsReducer.

我已经发布了关于这个的两个问题,我在这里看到的唯一真正的解决方案是我需要在我的减速器中有一个看起来像这样的条件:

I've posted two questions about this already and the only real solution I'm seeing here is that I need to have a condition in my reducer that looks like this:

...
case types.SET_DISABLED_DATES:
   if(typeof state.datePickers[action.datePickerId] !== "undefined") { // Making sure that what I'm trying to update exists in the reducer
      return Object.assign({}, state,
       datePickers: Object.assign({}, state.datePickers, {
          datePickers[action.datePickerId]: Object.assign({}, state.datePickers[action.datePickerId], {
             disabledBefore: action.value
          })
    })
   } else {
      return state;
   }

诚然,这看起来有点像杂七杂八的东西,但我真的想不出另一个解决方案.

Admittedly, this looks a bit like a kludge but I couldn't really come up with another solution here.

同样,问题是只要所有的 reducer 都响应 SET_DISABLED_DATES,就可以保证特定的日期选择器不会在那里,并且 Object.assign() 会抛出错误.

Again, the problem is that for as long as all reducers respond to SET_DISABLED_DATES, it's guaranteed that a particular date picker will not be there and the Object.assign() will throw an error.

有什么建议吗?减速器中的简单条件是要走的路吗?是杂牌吗?

Any suggestions? Is the simple condition in the reducer the way to go here? Is it a kludge?

附言我试过这段代码,它工作正常并解决了问题.一方面,我觉得这有点反模式,但另一方面,在尝试更新它之前确保我想要在我的减速器中更新的属性存在似乎是个好主意.我很感激你对此的反馈.谢谢.

P.S. I tried this code and it works fine and fixes the problem. On the one hand, I feel this is a bit of an anti-pattern but on the other hand, it just seems like a good idea to make sure the property I want to update in my reducer exists before attempting to update it. I'd appreciate your feedback on this. Thanks.

推荐答案

您只是在设置状态之前在 reducer 中进行基本验证.那完全没问题.我认为在操作创建器中检查存储以防止对不在存储中的对象分派操作(无论如何你会怎么做!),这不是一个好习惯.

You are just doing basic validation in the reducer before setting the state. That is perfectly fine. I don't think it will be a good practice to check the store in the action creator to prevent dispatching actions on objects not in the store (how would you do that anyway!).

我不明白的是,如何将日期选择器链接到不在商店中的另一个日期选择器?也许在组件的 didMountwillUnmount 上分派创建和拆卸操作?

What I don't understand is, how can a datepicker be linked to another datepicker that isn't in the store? Maybe dispatch a create and teardown action on the component's didMount and willUnmount?

我不知道您的全部要求,但我认为我们可以简化很多.我会做这样的事情:

I don't know your full requirements but I think we can make it a lot simpler. I'd do something like this:

店铺:

{
  datePickers: {
    id1: {
      value: '',
      minValue: '',
      maxValue: '',
    },
    id2: {
      value: '',
      minValue: '',
      maxValue: '',
    }
  }
}

现在,除非你制作某种总是成对运行的耦合日期选择器组件,我相信最干净的方法是在 mapDispactchToProps 函数中的链接日期选择器中设置禁用值您的父组件.

Now, unless you are making some kind of coupled datepicker components that will always behave in pairs, I believe the cleanest approach would be to set the disabled value in the linked datepicker in the mapDispactchToProps function in your parent component.

这是您将 ids 设置为组件的地方,并且您确切地知道应该在另一个组件之前禁用哪个组件.

That is where you would set ids to the components, and you know exactly which component should be disabled before another.

类似于:

dispatch => ({
  setArrivalDate(value) {
    dispatch(datePickerActions.setValue(arrivalDateId, value);
    dispatch(datePickerActions.setMaxValue(depatureDateId, value);
  },
  setDepatureDate(value) {
    dispatch(datePickerActions.setValue(depatureDateId, value);
    dispatch(datePickerActions.setMinValue(arrivalDateId, value);
  }
})

这可能不够抽象,但很干净.

This may not be abstract enough, but is clean.

如果您有配对的组件,您可以做同样的事情,但您仍然需要知道哪个日期在另一个日期之前.围绕它进行通用抽象会很麻烦.

You could do the same thing if you have a paired component, but you'd still need to know which date comes before another. It'd be a hassle to make a generic abstraction around it.

这篇关于减速器行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆