即使对所有状态数据进行深度复制,React Redux状态更改也不会导致更新

时间:2020-08-21 23:18:40

标签: javascript reactjs redux react-redux

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

我的reducer是单行返回状态,而新对象是action.payload。我的动作创建者读取了原始数据,克隆了所有数据(其中一些多次克隆以尝试解决此问题),然后将撤消动作和数据分派给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;
            }
        }
    }

编辑-添加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
    }
}

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

0 个答案:

没有答案