React-Redux更改后的状态未重新呈现

时间:2020-09-10 20:16:52

标签: javascript reactjs react-redux

我已经构建了一个相当大的react-redux应用程序。在一个组件中,我添加了撤消功能。一直跟踪状态,绝对是更新状态,而不是突变状态。它甚至重新渲染组件和所有子组件。但是,在页面上,直到我单击该组件以再次移动它或使其突出显示时,该组件的位置才被修改。

我已经确认这不是突变状态的情况,并且逐步执行了所有redux代码以确保浅相等性失败,并且在主要组件和应移动的子组件上添加了断点。 / p>

如果您想查看代码,我将添加代码,但是我的问题是,即使顶部和左侧坐标确实发生了变化,为什么React中重新渲染的组件也不会在屏幕上的更新位置重新渲染? / p>

编辑添加的代码

//layout.js

const mapLayoutDispatchToProps = (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_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_Undo_Change: (callback) => { dispatch(Layout_Undo_Change(callback)) },
        Layout_Redo_Change: () => { dispatch(Layout_Redo_Change()) },
        Layout_Fetch_Desks: (siteId) => { dispatch(Layout_Fetch_Desks(siteId)) },
        Layout_Get_Desk_Types: () => { dispatch(Layout_Get_Desk_Types()) },
        Layout_Set_Current_Desk: (desk) => { dispatch(Layout_Set_Current_Desk(desk)) }
    };
}

getDesks = () => {
    console.log("Layout.getDesks");
    // const d = this.props.layout_moveData.desks.present;
    const desks = clone(this.props.layout_moveData.present);
    return desks;
}

   handleKeyPress = (e) => {
        console.log("Layout.handleKeyPress");
        if (this.state.edit) {
            switch (e.code) {
                case 'KeyZ':
                    if (e.ctrlKey) {
                        this.props.Layout_Undo_Change();
                        e.cancelBubble = true;
                        // this.forceUpdate();
                    }
                    break;
                case 'KeyY':
                    if (e.ctrlKey) {
                        //this.props.Layout_Redo_Change();
                        UndoMove.redo();
                        e.cancelBubble = true;
                    }
                    break;
                default:
                    break;
            }
        }
    }

    buildDesks = () => {
        const desks = this.getDesks();
        let ret = desks.map((desk, index) =>
            <Desk
                key={index}
                desks={desks}
                index={index}
                deskTypes={this.props.layout.deskTypes}
                scale={this.getScale()}
                editable={this.state.edit}
            />
        );
        return ret;
    }

    render=()=>{

            return (
                <div>

                    <Row>
                        <Col sm={1}>
                            {this.showAdmin()}
                        </Col>
                        <Col sm={10}>
                            {this.state.details}
                        </Col>
                    </Row>
                    <Row>
                        <Col sm={1}>
                            <select onChange={(e) => this.changeMap(e.target)}>
                                {this.buildMapOptions()}
                            </select>
                        </Col>
                        <Col sm={10} id="Layout_Map_Container">
                            {this.buildMap()}
                            {this.buildDesks()}
                        </Col>
                    </Row >
                    {this.showStatus()}
                </div>
            );
        }
    }
//desks.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Draggable from '../../Elements/Draggable';

import {
    Layout_Clear_Desk,
    Layout_Delete_Desk,
    Layout_Update_Desk_Data,
    Layout_Set_Current_Desk
} from '../../../redux/Creators/Layout_Creator';

import '../../../shared/styles/layout.css';
const clone = require('rfdc')();

const mapDesksStateToProps = (state) => {
    return {
        layout: state.layout,
        layout_moveData: state.layout_moveData
    }
}

const mapDesksDispatchToProps = (dispatch) => {
    return {
        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_Set_Current_Desk: (deskId) => { dispatch(Layout_Set_Current_Desk(deskId)) }

    }
}

class Desk extends Component {

    constructor(props) {
        super(props);
        this.state = {
            desk: clone(props.desks[props.index]),
            desks: clone(props.desks)
        }
    }

    rightClick = (e, deskId) => {
        if (this.props.editable) {
            const desk = this.state.desk;
            let rotation = parseInt(desk.rotation);
            rotation += 90;
            if (rotation >= 360) rotation -= 360;
            desk.rotation = rotation;

            this.props.Layout_Set_Current_Desk(desk);
            this.props.Layout_Update_Desk_Data(desk);
        }
    }

    updateProperties = (data) => {
        let string = `Top: ${data.top}, Left:${data.left}`;
        // data = this.state.details + ', ' + data
        this.setState({ details: string });
    }

    mouseUp = (e, deskId, data) => {
        console.log("Layout.mouseUp");
        const desks = clone(this.state.desks);
        // let desk = ;
        if (data.dragged && this.props.editable) {
            // this.clickDesk(e, deskId);
            const scale = this.props.scale;
            const newX = parseInt(data.left / scale);
            const newY = parseInt(data.top / scale);

            desks[deskId].x = newX + ""; //convert to strings
            desks[deskId].y = newY + "";

            console.log(this.state.desks);
            console.log(desks);
            this.props.Layout_Update_Desk_Data(desks, deskId);
        }
        else {
            this.clickDesk(e, deskId);
        }

    }

    clickDesk = (e, deskId) => {
        if (deskId !== null && deskId !== undefined && deskId !== false) {

            this.props.Layout_Set_Current_Desk(this.state.desk);
        }
        else {
            this.props.Layout_Set_Current_Desk(null);
        }
    }


    render() {

        let deskImg = null;
        // const desk = this.props.desks[this.props.index];
        let desk = clone(this.state.desk);
        try {
            let dImg = this.props.deskTypes.find(
                d => parseInt(d.deskType) === parseInt(desk.deskType)
            );
            deskImg = dImg.deskImage;
        }
        catch (ex) {
            console.log(ex);
        }
        const userName = desk.UserLogon !== (null || '') ? desk.UserLogon : "Unassigned";

        const top = Math.trunc(parseInt(parseInt(desk.y) * this.props.scale));
        const left = Math.trunc(parseInt(parseInt(desk.x) * this.props.scale));

        let imgStyle = {
            width: `${parseInt(parseInt(desk.width) * this.props.scale)}px`,
            height: `${parseInt((parseInt(desk.height) * this.props.scale))}px`,

            position: 'absolute'
        }
        if (this.props.layout.currentDesk && desk.id === this.props.layout.currentDesk.id) {
            imgStyle.border = '2px solid cyan';
        }
        const url = `data:image/jpeg;base64,${deskImg}`;
        try {
            //
            return (
                <Draggable key={desk.id}
                    index={this.props.index}
                    enabled={this.props.editable}
                    left={left}
                    top={top}
                    onMove={this.updateProperties}
                    onStop={this.mouseUp}
                    onRightClick={this.rightClick}
                >
                    <div style={{
                        position: 'relative',
                        transform: `rotate(${parseInt(desk.rotation)}deg)`
                    }}
                        className='deskImg'>
                        <img style={imgStyle} alt={userName} src={url} />
                    </div>
                </Draggable>
            );
        }
        catch (ex) {
            console.log(ex);
            return null;
        }

    }//buildDesks
}

export default connect(mapDesksStateToProps, mapDesksDispatchToProps)(Desk);
//layout_creators.js 
export const Layout_Undo_Change = () => (dispatch, getState) => {
    const state = getState();
    const desks = clone(state.layout_moveData);
    console.log("1", state.layout_moveData.present)
    //if no past to undo to
    if (desks.past.length === 0) return;
    const previous = clone(desks.past[desks.past.length - 1]);
    desks.past.shift();
    const undoPast = clone(desks.past);
    // const undoPast = clone(desks.past).slice(0, desks.past.length - 1);
    const undoFuture = [clone(desks.present), ...clone(desks.future)]
    const undoDesks = { past: undoPast, present: previous, future: undoFuture };
    dispatch({ type: ActionTypes.LAYOUT_UNDO_MOVES, payload: clone(undoDesks) });
    console.log("2", state.layout_moveData.present)
    let init = fetchInit();
    init.method = "POST";
    const deskData = { mode: 'UPDATEMANY', data: previous };
    init.body = JSON.stringify(deskData);
    let myReq = new Request(`/dataAPI/Layout/`, init);
    fetch(myReq)
        .then((response) => {
            if (response.ok) {
                return response;
            }
            else {
                var error = new Error("Error " + response.statusText);
                error.response = response;
                throw error;
            }
        }, (error) => {
            var err = new Error(error.message);
            throw err;
        })

        .catch(err => {
            return dispatch({
                type: ActionTypes.LAYOUT_FAILED,
                payload: err.message
            });
        });
}
//layout_reducer.js
import * as ActionTypes from '../ActionTypes';

export const layout = (state = {
    isLoading: true,
    isLoadingMap: false,
    isLoadingDesks: false,
    desksLoaded: false,
    mapLoaded: false,
    currentMap: null,
    currentDesk: null,
    maps: [],
    deskTypes: [],
    editMode: false,
    errMess: null
}, action) => {
    switch (action.type) {
        case ActionTypes.LAYOUT_SITES_LOADING:
            return { ...state, isLoading: true };
        case ActionTypes.LAYOUT_DESKS_LOADING:
            return { ...state, isLoadingDesks: true, desksLoaded: false };
        case ActionTypes.LAYOUT_MAP_LOADING:
            return {
                ...state, isLoadingMap: true, desks: [],
                currentDesk: null, editMode: false, desksLoaded: false
            };
        case ActionTypes.LAYOUT_MAP_LOADED:
            return { ...state, isLoadingMap: false, mapLoaded: true, maps: action.payload };
        case ActionTypes.LAYOUT_MAPS_LOADED:
            return { ...state, maps: action.payload, isLoading: false };
        case ActionTypes.LAYOUT_DESKTYPES_LOADED:
            return { ...state, deskTypes: action.payload };

        case ActionTypes.LAYOUT_SET_CURRENT_DESK:
            return { ...state, currentDesk: action.payload };
        case ActionTypes.LAYOUT_SET_EDITMODE:
            return { ...state, editMode: action.payload };
        case ActionTypes.LAYOUT_DESK_DELETED:
            return { ...state, currentDesk: null }
        case ActionTypes.LAYOUT_DESKS_LOADED:
            return { ...state, currentDesk: null, isLoadingDesks: false, desksLoaded: true }

        case ActionTypes.LAYOUT_SET_ACTIVE_MAP:
            return { ...state, currentMap: action.payload, desksLoaded: false };

        case ActionTypes.LAYOUT_FAILED:
            return {
                ...state, isLoadingMap: false, isLoadingDesks: false, desksLoaded: false,
                errMess: action.payload, pageUsageData: []
            };
        case ActionTypes.LAYOUT_RESTORE_ALL:
            return {
                ...state,
                isLoading: true, isLoadingMap: false, mapLoaded: false, currentMap: null,
                maps: [], desks: [], deskTypes: [], editMode: false,
                errMess: null, desksLoaded: false
            }
        default:
            return state;
    }
}

export const layout_moveData = (state = {

    past: [],
    present: null,
    future: []

}, action) => {

    switch (action.type) {
        case ActionTypes.LAYOUT_DESKS_LOADING:
            return { ...state, present: [], past: [], future: [] };
        case ActionTypes.LAYOUT_DESKS_LOADED:
            return { ...state, present: action.payload, past: [], future: [] };
        case ActionTypes.LAYOUT_DESK_DELETED:
            return { ...state, present: action.payload.present, past: action.payload.past, future: action.payload.future };
        case ActionTypes.LAYOUT_RESTORE_ALL:
            return { ...state, present: [], past: [], future: [] };
        case ActionTypes.LAYOUT_SET_MOVES:
            return { ...state, present: action.payload.present, past: action.payload.past, future: action.payload.future };
        case ActionTypes.LAYOUT_UNDO_MOVES:
            return { ...state, present: action.payload.present, past: action.payload.past, future: action.payload.future };
        case ActionTypes.LAYOUT_REDO_MOVES:
            return { ...state, present: action.payload.present, past: action.payload.past, future: action.payload.future };
        default:
            return state
    }
}

0 个答案:

没有答案