繁体   English   中英

未捕获的不变违规:使用 arrayMove 时在调度之间检测到 state 突变

[英]Uncaught Invariant Violation: A state mutation was detected between dispatches when using arrayMove

我正在尝试构建一个 React/Redux 应用程序,我是一个初学者。 我想使用 React Sortable HOC 来获得一个可重新排列的列表,但我无法坚持新的安排。 我有一个功能组件,可以在其中获取项目列表。 项目结构是这样的:项目 [ {name, courseList}, {name, courseList}, ...]。

为了填充表格,我调用了 api 并使用 MapStateToProps 更新了 prop 变量。 这是一段代码:

function CoursesPage({
  student,
  studentCourses,
  loadStudentCourses,
  updateCoursesOrder,
  ...props
}) {
  useEffect(() => {
    if (studentCourses.length === 0) {
      loadStudentCourses(student.id).catch((error) => {
        alert("Loading student courses failed" + error);
      });
    }
  }, []);
...
}

这是 mapStateToProps function:

function mapStateToProps(state) {
  return {
    student: state.student,
    studentCourses: state.studentCourses,
  };
}

这一点工作正常,一切都出现了。 问题是当我尝试重新排列并将其保存在 onSortEnd function 中时:

  function onSortEnd({ oldIndex, newIndex, collection }) {
    const newCollections = [...studentCourses];

    newCollections[collection].courseList = arrayMove(
      newCollections[collection].courseList,
      oldIndex,
      newIndex
    );

    updateCoursesOrder(newCollections);
  }

newCollection 被正确填充和修改,我正在调用 updateCoursesOrder 并正确排列项目。 function 是一个调用调度的动作。

export function updateCoursesOrder(courseList) {
  return function (dispatch) {
    dispatch(setNewCourseOrderSuccess(courseList));
  };
}

export function setNewCourseOrderSuccess(studentCourses) {
  return { type: types.SET_NEW_COURSE_ORDER, studentCourses };
}

使用调试器,我可以看到代码运行良好,直到从 setNewCourseOrderSuccess() 调度返回。

这应该 go 到减速器,但会引发错误:未捕获的不变违规:在调度之间检测到 state 突变。

这是减速器的样子:

export default function courseReducer(
  state = initialState.studentCourses,
  action
) {
  switch (action.type) {
    case type.LOAD_STUDENT_COURSES_SUCCESS:
      return action.studentCourses;
    case type.SET_NEW_COURSE_ORDER:
      return {
        ...state,
        studentCourses: action.payload,
      };
    default:
      return state;
  }
}

我该如何解决这个问题? 非常感谢!

有了这个:

const newCollections = [...studentCourses];

newCollections[collection].courseList =

虽然newCollections是一个新数组,但它只是studentCourses的浅拷贝; 数组项不是克隆,它们是对 state 中当前对象的引用。 因此,分配给这些对象之一的courseList属性正在改变 state。

替换索引处的 object 而不是对其进行变异:

function onSortEnd({ oldIndex, newIndex, collection }) {
    updateCoursesOrder(studentCourses.map((item, i) => i !== collection ? item : ({
        ...item,
        courseList: arrayMove(item.courseList, oldIndex, newIndex)
    })));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM