[英]Redux A state mutation was detected before reach the reducer
我從視圖發送到一個動作this.props.appClasses這是視圖:
<div key={key} className='SDWanAppClassTreeItem' onClick={this.props.actions.handleToggleAppClass.bind(this,this.props.appClasses, 0, key)}>
在我修改從視圖中獲得的appClasses的操作中,我想將修改后的appClasses發送到reducer以更新appClasses狀態。 但這在到達減速器之前給了我一個錯誤。
檢測到狀態突變這是操作:
export function handleToggleAppClass(appClasses, parentAppClassId, appClassId) {
// console.log('handleToggleAppClass', appClassId, this.appClasses[appClassId]);
if (appClass.parentAppClassId == 0) {
// Flip the appClass Show Property
appClasses[appClass.appClassId].show = appClasses[appClass.appClassId].show ? false : true;
if (Object.keys(appClasses[appClass.appClassId].children).length !== 0) {
// Regardless if we enable or disabled the parent, all children should be disabled
for (var childKey in appClasses[appClass.appClassId].children) {
appClasses[appClass.appClassId].children[childKey].show = false;
}
}
} else {
// If we are enabling a child, make sure parent is disabled
if (!appClasses[appClass.parentAppClassId].children[appClass.appClassId].show) {
appClasses[appClass.parentAppClassId].show = false;
}
appClasses[appClass.parentAppClassId].children[appClass.appClassId].show = appClasses[appClass.parentAppClassId].children[appClass.appClassId].show ? false : true;
}
dispatch(handleUpdateInitialSourceFetch(appClasses));
return { type: types.TOGGLE_APP_CLASS, appClasses };
}
如您所見,我確實想在操作上修改appClasses,因為我必須使用新修改的appClasses來更新另一個reducer上的另一個狀態。 在這里,我想修改appClasses的狀態(在一個reducer中),並通過在其他操作dispatch(handleUpdateInitialSourceFetch(appClasses))的函數調用中分派修改后的appClasses; 我想修改另一個狀態selection.appClassesIds(在另一個處理用戶選擇的reducer中):
const selection = {
timespan: "-3660",
direction: 0,
appClassIds: []
};
export function updateAppClassesIds(appClasses) {
var appClassIds = [];
for (var key in appClasses) {
if (appClasses[key].show) appClassIds.push(key);
if (Object.keys(appClasses[key].children).length !== 0) {
// Regardless if we enable or disabled the parent, all children should be disabled
for (var childKey in appClasses[key].children) {
if (appClasses[key].children[childKey].show) appClassIds.push(childKey);
}
}
}
return { type: types.UPDATE_APP_CLASSES_IDS, appClassIds };
}
如何將appClasses變量從視圖發送到操作,而不會出現該錯誤。 還是應該將selection和appClasses狀態置於一個大狀態中,以便因為這兩個狀態相互依賴而能夠訪問這兩個狀態?
您可以通過創建一個操作來接收要修改的appClass的ID和新值(true / false)來實現此目的。
然后,Reducer應該能夠處理對您的狀態的更新,然后通過訂閱的組件進行傳播。
我的意思是,“切換應用程序類”的某些內容的適當負載不是應用程序類的完整列表,而是更接近:
{
type: types.TOGGLE_APP_CLASS,
payload: appClass.appClassId
}
狀態修改應在化簡器中進行-這就是化簡器的用途 。
減速器是一個純函數,它采用上一個狀態和一個動作,然后返回下一個狀態。
您正在嘗試(a)在操作創建者中直接修改狀態,並且(b)嘗試在錯誤的位置修改狀態。 一旦您開始在正確的位置進行操作,則更容易解決此問題。
在化簡器中,您可以slice
(如果這是一個數組),也可以進行對象克隆以更新單個切換並將狀態設置為此新狀態副本。 但是,您不會直接改變狀態。 這樣做會破壞Redux帶來的很多好處(例如,時間旅行)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.