edd*_*ddy 3 javascript ecmascript-6 reactjs redux react-redux
我知道之前已经问过这个问题,但几乎所有人都在谈论OP直接改变状态,我试图避免使用像扩展运算符这样的技术(在对象和数组中),但尽管如此我得到以下错误:
Uncaught Error: A state mutation was detected between dispatches, in the path `courses.0`. This may cause incorrect behavior. (http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments)
at invariant (eval at <anonymous> (bundle.js:922), <anonymous>:40:15)
at eval (eval at <anonymous> (bundle.js:3825), <anonymous>:50:36)
at eval (eval at <anonymous> (bundle.js:3846), <anonymous>:14:16)
at dispatch (eval at <anonymous> (bundle.js:3853), <anonymous>:37:18)
at eval (eval at <anonymous> (bundle.js:1151), <anonymous>:63:5)
at eval (eval at <anonymous> (bundle.js:3846), <anonymous>:11:18)
at Object.eval [as saveCourse] (eval at <anonymous> (bundle.js:3860), <anonymous>:4:12)
at Object.ManageCoursePage._this.saveCourse [as onSave] (eval at <anonymous> (bundle.js:2080), <anonymous>:134:27)
at CourseForm._this.onHandleSave (eval at <anonymous> (bundle.js:2052), <anonymous>:93:19)
at Object.ReactErrorUtils.invokeGuardedCallback (eval at <anonymous> (bundle.js:1301), <anonymous>:69:16)
Run Code Online (Sandbox Code Playgroud)
我读了错误指向的文章,并且它建议我检查我是否在我的reducer中手动改变状态,我看不到可能发生的情况:
const courseReducer = (state = initialState.courses, action) => {
switch (action.type) {
case types.LOAD_COURSE_SUCCESS:
return action.courses;
case types.CREATE_COURSE_SUCCESS:
//This action throw the error
debugger;
return [
...state,
Object.assign({}, action.course)
];
case types.UPDATE_COURSE_SUCCESS:
//This action throw the error
debugger;
return [
...state.filter(course => course.id !== action.course.id),
Object.assign({}, action.course)
];
case types.DELETE_COURSE_SUCCESS:
return [...state.filter(course => course.id !== action.courseId)];
default:
return state;
}
};
Run Code Online (Sandbox Code Playgroud)
这是一个沙盒,其中包含可用于复制错误的应用程序的一部分,奇怪的是,只有在我创建新课程或尝试编辑现有课程时才会发生这种情况(动作CREATE_COURSE_SUCCESS和UPDATE_COURSE_SUCCESS我的courseReducer)
我真的很感激,如果有人能帮助我弄清楚哪里可能是这个错误的根源.
问题是你正在改变状态,内部CoursesPage.js,在mapStateToProps:
let courses = state.courses.sort((c1, c2) =>
c1.title.localeCompare(c2.title, 'en', { sensitivity: 'base' }),
);
Run Code Online (Sandbox Code Playgroud)
Array#sort是一个就地操作,因此它通过对源数组进行排序来改变源数组.这意味着,sort正在发生变异state.courses,从而导致错误.而是state.courses在排序之前复制一份:
[...state.courses]
Run Code Online (Sandbox Code Playgroud)
上面使用扩展语法将元素分散到一个新的数组中,基本上克隆它.这是一样的Array#slice.然后你可以这样排序:
let courses = [...state.courses].sort((c1, c2) =>
c1.title.localeCompare(c2.title, 'en', { sensitivity: 'base' }),
);
Run Code Online (Sandbox Code Playgroud)
这不会改变原件state.courses,也不会抛出错误.
注意:在某些地方您可以this.state直接进行变异,例如在第32 ManageCoursePage.js行:
this.state.errors = {}
Run Code Online (Sandbox Code Playgroud)
只有this.state在组件的构造函数中改变对象.请setState改用.
| 归档时间: |
|
| 查看次数: |
1963 次 |
| 最近记录: |