据我了解,当调用一个操作时,所有减速器都会做出响应。如果动作存在于switch case
的reducer语句,它执行。如果没有,那么case: default
执行保留现有状态。
当该操作存在于减速器中但它尝试更新的特定属性不存在时,它似乎表现正常,因为没有任何可更新的内容。
例如,我有一个动作创建器,用于设置visible
我的模态属性。每个模态都有自己的Id
。我的代码如下所示:
export default (state = initialState, action) => {
case types.SET_MODAL_IS_VISIBLE:
return Object.assign({}, state,
{ modal22: action.value }
)}
我有SET_MODAL_IS_VISIBLE
在多个减速器中,但是如果modal22
没有在特定的减速器中定义,没有任何反应,也没有错误。
现在,我有一个抛出错误的场景。我构建了一个通用日期选择器组件,可以用作单个独立的日期选择器,也可以“链接到”另一个日期选择器。如果我需要用户给我两个日期,例如,第二个场景很有用。开始和结束日期。
我还构建了一个功能,如果日期选择器与另一个日期选择器结合使用,当用户在第一个日期选择器中设置日期时,我会在第二个日期选择器中禁用该日期之前的所有日期,因为我不希望用户无意中选择了早于开始日期的结束日期。
我定义我的日期选择器如下:
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: ""
}
}
}
这种情况有点有趣,因为我的减速器中一个属性的状态更改正在触发另一个属性的状态更改。这并不难做到,而且我有办法控制更新的时间。
设置禁用日期的操作如下所示:
...
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
在每个减速机中。
我遇到的问题是每当我打电话时SET_DISABLED_DATES
,我在减速器中遇到错误,其中日期选择器用作单个/独立的日期选择器,因为其对的日期选择器 ID 未在减速器中定义。
例如,在projectsReducer
我可以使用日期选择器作为一对的一部分,所以两者startDatePicker
and endDatePicker
已定义并且一切正常。
但我可能在中使用单实例日期选择器tasksReducer
这也响应了SET_DISABLED_DATES
调用但失败,因为找不到endDatePicker
。在这种情况下,tasksReducer
正在响应我设置的调用disabledDates
的财产endDatePicker
in projectsReducer
.
我已经发布了两个关于此问题的问题,我在这里看到的唯一真正的解决方案是我需要在我的减速器中有一个如下所示的条件:
...
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;
}
诚然,这看起来有点像拼凑,但我真的无法在这里想出另一个解决方案。
同样,问题是只要所有减速器都响应SET_DISABLED_DATES
,保证特定的日期选择器不会出现,并且Object.assign()
会抛出错误。
有什么建议么?减速器中的简单条件是这里的方法吗?这是一个拼凑吗?
附:我尝试了这段代码,它工作正常并解决了问题。一方面,我觉得这有点反模式,但另一方面,在尝试更新之前确保我要在减速器中更新的属性存在似乎是个好主意。我非常感谢您对此的反馈。谢谢。