即使在深度复制所有状态数据后,React redux 状态更改也不会导致更新

IT技术 javascript reactjs redux react-redux
2021-05-08 13:16:21

我有一个组件,在使用时CTRL+Z应该触发撤消操作。跟踪代码很明显,状态已正确更新,并且其中的数组没有发生变异。但是,在我单击它之前不会重新渲染该组件,这会导致突出显示。此时组件跳转到它之前的位置。我尝试在调度撤消操作后使用 forceUpdate() 但也没有成功。

我的减速器是单行返回状态和新对象作为 action.payload。我的动作创建者读取原始数据,克隆所有内容(其中一些在“疯狂摆动”尝试解决这个问题时多次克隆),然后将撤消动作和数据分派给减速器。

单步执行代码并比较值向我表明一切似乎都是正确的,所以我看不出问题出在哪里。

这是我的动作创建者:

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;
            }
        }
    }

编辑 - 添加 mapState 代码

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)) }
    };
}

mapStateToProps 代码:

const mapStateToProps = (state) => {
    return {
        layout: state.layout,
        layout_moveData: state.layout_moveData,
        roles: state.siteMap.siteMapData.userRoles
    }
}

任何帮助我指明正确方向的帮助都会很棒。

1个回答

将所有组件和项目外推到单独的类以更好地处理单个状态更改,而不是自上而下地处理所有内容