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。存储正在维护,状态正在正确更改。除了页面上的位置没有被更新之外,一切都很正常。即使在重新渲染时传递的顶部和左侧坐标也是正确的,但它没有显示在正确的位置。