Javascript React redux状态更改即使在深度复制所有状态数据后也不会导致更新
我有一个组件,当使用Javascript React redux状态更改即使在深度复制所有状态数据后也不会导致更新,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我有一个组件,当使用CTRL+Z时,它应该触发撤销操作。通过跟踪代码可以明显看出,状态已正确更新,并且其中的数组没有发生变化。但是,在我单击该组件之前,不会重新渲染该组件,这会导致高亮显示。此时,零部件将跳到其以前的位置。我尝试在调度撤消操作后使用forceUpdate(),但也没有成功 我的reducer是一个单行返回状态,新对象是action.payload。我的action creator读取原始数据,克隆所有内容(其中一些内容多次以“疯狂摆动”的方式尝试解决此问题),然后将撤消操作和数据
CTRL+Z
时,它应该触发撤销操作。通过跟踪代码可以明显看出,状态已正确更新,并且其中的数组没有发生变化。但是,在我单击该组件之前,不会重新渲染该组件,这会导致高亮显示。此时,零部件将跳到其以前的位置。我尝试在调度撤消操作后使用forceUpdate(),但也没有成功
我的reducer是一个单行返回状态,新对象是action.payload。我的action creator读取原始数据,克隆所有内容(其中一些内容多次以“疯狂摆动”的方式尝试解决此问题),然后将撤消操作和数据发送到reducer
通过代码和比较值,我发现一切似乎都是正确的,所以我看不出问题出在哪里
这是我的行动创造者:
export const Layout_Undo_Change = (callback) => (dispatch, getState) => {
const state = getState();
const desks = state.layout_moveData.desks;
//if no past to undo to
if (desks.past.length === 0) return;
const previous = clone(desks.past)[desks.past.length - 1];
const undoPast = clone(desks.past.slice(0, desks.past.length - 1));
const undoFuture = clone([desks.present, ...clone(desks.future)])
const undoDesks = { past: undoPast, future: undoFuture, present: previous };
dispatch({ type: ActionTypes.LAYOUT_UNDO_MOVES, payload: undoDesks });
// callback();
}
这是减速器:
export const layout_moveData = (state = {
desks: {
past: [],
present: null,
future: []
}
}, action) => {
switch (action.type) {
case ActionTypes.LAYOUT_DESKS_LOADING:
return { ...state, desks: { present: [], past: [], future: [] } };
case ActionTypes.LAYOUT_DESKS_LOADED:
return { ...state, desks: { present: action.payload, past: [], future: [] } };
case ActionTypes.LAYOUT_DESK_DELETED:
return { ...state, desks: action.payload };
case ActionTypes.LAYOUT_RESTORE_ALL:
return { ...state, desks: { present: [], past: [], future: [] } };
case ActionTypes.LAYOUT_SET_MOVES:
return { ...state, desks: action.payload };
case ActionTypes.LAYOUT_UNDO_MOVES:
return { ...state, desks: action.payload };
case ActionTypes.LAYOUT_REDO_MOVES:
return { ...state, desks: action.payload };
default:
return state
}
}
最后是来自组件的调用线路:
handleKeyPress = (e) => {
console.log("Layout.handleKeyPress");
if (this.state.edit) {
switch (e.code) {
case 'KeyZ':
if (e.ctrlKey) {
this.props.Layout_Undo_Change(this.forceUpdate);
e.cancelBubble = true;
this.forceUpdate();
}
break;
case 'KeyY':
if (e.ctrlKey) {
//this.props.Layout_Redo_Change();
UndoMove.redo();
e.cancelBubble = true;
}
break;
default:
break;
}
}
}
编辑-添加地图状态代码
mapDispatchToProps代码:
const mapDispatchToProps = (dispatch) => {
//add action creators here - by reference?
return {
Layout_Set_Current_Site: (siteId) => { dispatch(Layout_Set_Current_Site(siteId)) },
Layout_Get_Sites: () => { dispatch(Layout_Get_Sites()) },
Layout_Get_Map_Background: (siteId, callback) => { dispatch(Layout_Get_Map_Background(siteId, callback)) },
Layout_Get_Desk_Types: () => { dispatch(Layout_Get_Desk_Types()) },
Layout_Fetch_Desks: (siteId) => { dispatch(Layout_Fetch_Desks(siteId)) },
Layout_Undo_Change: (callback) => { dispatch(Layout_Undo_Change(callback)) },
Layout_Redo_Change: () => { dispatch(Layout_Redo_Change()) },
Layout_Clear_Desk: (deskId) => { dispatch(Layout_Clear_Desk(deskId)) },
Layout_Delete_Desk: (deskId) => { dispatch(Layout_Delete_Desk(deskId)) },
Layout_Update_Desk_Data: (desk, deskId) => { dispatch(Layout_Update_Desk_Data(desk, deskId)) },
Layout_Get_UserImages: (deskId) => { dispatch(Layout_Get_UserImages(deskId)) },
Layout_Create_Desk: (type, siteId, height, width) => { dispatch(Layout_Create_Desk(type, siteId, height, width)) },
Layout_Restore_All: () => { dispatch(Layout_Restore_All()) },
Layout_Set_Current_Desk: (deskId) => { dispatch(Layout_Set_Current_Desk(deskId)) }
};
}
const mapStateToProps = (state) => {
return {
layout: state.layout,
layout_moveData: state.layout_moveData,
roles: state.siteMap.siteMapData.userRoles
}
}
mapStateToProps代码:
const mapDispatchToProps = (dispatch) => {
//add action creators here - by reference?
return {
Layout_Set_Current_Site: (siteId) => { dispatch(Layout_Set_Current_Site(siteId)) },
Layout_Get_Sites: () => { dispatch(Layout_Get_Sites()) },
Layout_Get_Map_Background: (siteId, callback) => { dispatch(Layout_Get_Map_Background(siteId, callback)) },
Layout_Get_Desk_Types: () => { dispatch(Layout_Get_Desk_Types()) },
Layout_Fetch_Desks: (siteId) => { dispatch(Layout_Fetch_Desks(siteId)) },
Layout_Undo_Change: (callback) => { dispatch(Layout_Undo_Change(callback)) },
Layout_Redo_Change: () => { dispatch(Layout_Redo_Change()) },
Layout_Clear_Desk: (deskId) => { dispatch(Layout_Clear_Desk(deskId)) },
Layout_Delete_Desk: (deskId) => { dispatch(Layout_Delete_Desk(deskId)) },
Layout_Update_Desk_Data: (desk, deskId) => { dispatch(Layout_Update_Desk_Data(desk, deskId)) },
Layout_Get_UserImages: (deskId) => { dispatch(Layout_Get_UserImages(deskId)) },
Layout_Create_Desk: (type, siteId, height, width) => { dispatch(Layout_Create_Desk(type, siteId, height, width)) },
Layout_Restore_All: () => { dispatch(Layout_Restore_All()) },
Layout_Set_Current_Desk: (deskId) => { dispatch(Layout_Set_Current_Desk(deskId)) }
};
}
const mapStateToProps = (state) => {
return {
layout: state.layout,
layout_moveData: state.layout_moveData,
roles: state.siteMap.siteMapData.userRoles
}
}
任何能为我指明正确方向的帮助都会非常棒。您能显示您的代码吗?您的代码实际上正在从组件中的存储读取数据(即,
mapState
或useSelector
)?另外,请注意,您应该真正使用,这将大大简化所有逻辑,而且@markerikson我已经添加了mapDispatch和mapState。我还将查看工具包包。@HMR我还没有查看devtools,但在逐步查看代码时,我比较了更改,知道传递到状态的变量是正确的,并且状态也相应地更新了。我担心的是,在某个地方我正在操纵状态,但不确定在哪里。一定要从使用Redux开发工具开始。行动真的被派遣了吗?州政府是否按照你预期的方式进行了更新?然后,您的mapState
运行了吗?mapState
返回的数据是否与上次运行时的数据不同?另外,另一方面要注意:如果要使用connect
,则应使用而不是将其作为函数编写。它将是wayyy更短:)@markerikson我一直在使用DevTools。存储正在维护,状态正在正确更改。除了页面上的位置没有被更新之外,一切都很正常。即使在重新渲染时传递的顶部和左侧坐标都是正确的,但它没有显示在正确的位置。您是否可以显示实际从组件中的存储读取数据的代码(即,mapState
或useSelector
)?另外,请注意,您应该真正使用,这将大大简化所有逻辑,而且@markerikson我已经添加了mapDispatch和mapState。我还将查看工具包包。@HMR我还没有查看devtools,但在逐步查看代码时,我比较了更改,知道传递到状态的变量是正确的,并且状态也相应地更新了。我担心的是,在某个地方我正在操纵状态,但不确定在哪里。一定要从使用Redux开发工具开始。行动真的被派遣了吗?州政府是否按照你预期的方式进行了更新?然后,您的mapState
运行了吗?mapState
返回的数据是否与上次运行时的数据不同?另外,另一方面要注意:如果要使用connect
,则应使用而不是将其作为函数编写。它将是wayyy更短:)@markerikson我一直在使用DevTools。存储正在维护,状态正在正确更改。除了页面上的位置没有被更新之外,一切都很正常。即使在重新渲染时传递的顶部和左侧坐标也是正确的,但它没有显示在正确的位置。