未捕获的不变违规:使用 arrayMove 时在分派之间检测到状态突变
Uncaught Invariant Violation: A state mutation was detected between dispatches when using arrayMove
我正在尝试构建一个 React/Redux 应用程序,我是初学者。我想使用 React Sortable HOC 来获得一个可重新排列的列表,但我无法坚持新的排列。
我有一个功能组件,可以在其中获取项目列表。项目结构是这样的:
项目 [ {name, courseList}, {name, courseList}, ...].
为了填充 table,我调用了 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 mapStateToProps(state) {
return {
student: state.student,
studentCourses: state.studentCourses,
};
}
这个位工作正常,一切都出现了。
问题是当我尝试重新排列并将其保存在 onSortEnd 函数中时:
function onSortEnd({ oldIndex, newIndex, collection }) {
const newCollections = [...studentCourses];
newCollections[collection].courseList = arrayMove(
newCollections[collection].courseList,
oldIndex,
newIndex
);
updateCoursesOrder(newCollections);
}
newCollection 被正确填充和修改,我正在调用 updateCoursesOrder 并正确排列项目。该函数是调用调度的操作。
export function updateCoursesOrder(courseList) {
return function (dispatch) {
dispatch(setNewCourseOrderSuccess(courseList));
};
}
export function setNewCourseOrderSuccess(studentCourses) {
return { type: types.SET_NEW_COURSE_ORDER, studentCourses };
}
使用调试器,我可以看到代码 运行 很好,直到从 setNewCourseOrderSuccess() 调度 return。
这应该转到减速器,但会抛出错误:未捕获的不变违规:在分派之间检测到状态突变。
reducer 是这样的:
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
的浅拷贝;数组项不是克隆,它们是对状态中当前对象的引用。因此,分配给其中一个对象的 courseList
属性 会改变状态。
替换索引处的对象而不是改变它:
function onSortEnd({ oldIndex, newIndex, collection }) {
updateCoursesOrder(studentCourses.map((item, i) => i !== collection ? item : ({
...item,
courseList: arrayMove(item.courseList, oldIndex, newIndex)
})));
}
我正在尝试构建一个 React/Redux 应用程序,我是初学者。我想使用 React Sortable HOC 来获得一个可重新排列的列表,但我无法坚持新的排列。 我有一个功能组件,可以在其中获取项目列表。项目结构是这样的: 项目 [ {name, courseList}, {name, courseList}, ...].
为了填充 table,我调用了 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 mapStateToProps(state) {
return {
student: state.student,
studentCourses: state.studentCourses,
};
}
这个位工作正常,一切都出现了。 问题是当我尝试重新排列并将其保存在 onSortEnd 函数中时:
function onSortEnd({ oldIndex, newIndex, collection }) {
const newCollections = [...studentCourses];
newCollections[collection].courseList = arrayMove(
newCollections[collection].courseList,
oldIndex,
newIndex
);
updateCoursesOrder(newCollections);
}
newCollection 被正确填充和修改,我正在调用 updateCoursesOrder 并正确排列项目。该函数是调用调度的操作。
export function updateCoursesOrder(courseList) {
return function (dispatch) {
dispatch(setNewCourseOrderSuccess(courseList));
};
}
export function setNewCourseOrderSuccess(studentCourses) {
return { type: types.SET_NEW_COURSE_ORDER, studentCourses };
}
使用调试器,我可以看到代码 运行 很好,直到从 setNewCourseOrderSuccess() 调度 return。
这应该转到减速器,但会抛出错误:未捕获的不变违规:在分派之间检测到状态突变。
reducer 是这样的:
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
的浅拷贝;数组项不是克隆,它们是对状态中当前对象的引用。因此,分配给其中一个对象的 courseList
属性 会改变状态。
替换索引处的对象而不是改变它:
function onSortEnd({ oldIndex, newIndex, collection }) {
updateCoursesOrder(studentCourses.map((item, i) => i !== collection ? item : ({
...item,
courseList: arrayMove(item.courseList, oldIndex, newIndex)
})));
}