簡體   English   中英

Redux在到達減速器之前檢測到狀態突變

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM