Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript componentDidUpdate中的先前状态和当前状态相等_Javascript_Reactjs_Axios - Fatal编程技术网

Javascript componentDidUpdate中的先前状态和当前状态相等

Javascript componentDidUpdate中的先前状态和当前状态相等,javascript,reactjs,axios,Javascript,Reactjs,Axios,在每个模块的仪表板中,其布局数据(使用react grid layout)与模块数据分开存储,并且每个布局数据存储在数据库中。当前模块数据和布局数据存储在仪表板组件状态中。每当模块或布局的先前状态与当前状态不同时,我尝试在componentDidMount()中调用单独的axios POST请求,以保存数据库中的更改。但是通过调试和日志记录,我发现prevState等于this.state 以下是更改相关状态的方法和componentDidMount()方法: componentDidUpdat

在每个模块的仪表板中,其布局数据(使用react grid layout)与模块数据分开存储,并且每个布局数据存储在数据库中。当前模块数据和布局数据存储在仪表板组件状态中。每当模块或布局的先前状态与当前状态不同时,我尝试在
componentDidMount()
中调用单独的axios POST请求,以保存数据库中的更改。但是通过调试和日志记录,我发现
prevState
等于
this.state

以下是更改相关状态的方法和
componentDidMount()
方法:

componentDidUpdate(prevProps, prevState) {
// JSON.stringify comparison for proof of concept since the order does not change
        if(JSON.stringify(prevState.modules) !== JSON.stringify(this.state.modules))
            API.post('Adminusers/StoreUserModuleData', "module_data=" + JSON.stringify(this.state.modules))
                        .then((res) => console.log(res))
                        .catch(err => {throw new Error(err)});
        if(JSON.stringify(prevState.layouts) !== JSON.stringify(this.state.layouts))
            API.post('Adminusers/StoreAdminUserLayouts', "layouts=" + JSON.stringify(this.state.layouts))
                        .then((res) => console.log(res))
                        .catch(err => {throw new Error(err)});  
    }

addNewModuleInLayout(moduleData) {

        let newLayout = this.state.layouts;
        let newModule = this.state.modules;

        for (let key in newLayout) {
            if (newLayout.hasOwnProperty(key)) {
                newLayout[key].push({
                    i: moduleData.type,
                    x: (newLayout[key].length * 1) % 3,
                    y: Infinity,
                    w: 1,
                    h: 5
                });
            }
        }

        newModule.push(moduleData);

        this.setState({layouts: newLayout, modules: newModule})
    }

removeModule(layoutId, type) {
        let newLayout = this.state.layouts;
        let newModule = this.state.modules;

        for (let key in newLayout)
            newLayout[key] = newLayout[key].filter(item => { return item.i !== layoutId })

        newModule = newModule.filter(item => {return item.type != type}); 

        this.setState({ modules: newModule, layouts: newLayout });
    }

某个模块的模块数据和布局数据示例如下:

// layouts
{
 "md": [{ i: "current-user", x: 0, y: 0, w: 3, h: 5, isDraggable: false, isResizable: true }],
 "lg": [{ i: "current-user", x: 0, y: 0, w: 3, h: 5, isDraggable: false, isResizable: true }],
 "sm": [{ i: "current-user", x: 0, y: 0, w: 3, h: 5, isDraggable: false, isResizable: true }],
 "xs": [{ i: "current-user", x: 0, y: 0, w: 3, h: 5, isDraggable: false, isResizable: true }]
}

// module data
[{ type: "current-user", content: " ", title: "Current User Module" }]

有谁能告诉我这两种状态相等时我做错了什么吗?

尝试在
addNewModuleInLayout
removeModule
中更新数组声明

const newLayout = { ...this.state.layouts }; // from let newLayout = this.state.layouts
const newModule = [...this.state.modules]; // from let newModule = this.state.modules
在cDM中,您不会在状态上创建模块/布局阵列的“新”副本,而是直接引用阵列。当你更新数组时,你实际上改变了你的状态,因此当你将
prevState
this.state
区分时,字符串化的版本是相等的

但这不会深入复制layouts对象,因此在推送到布局阵列时会遇到同样的问题。您可以在更新布局时创建一个新数组,而不是按

newLayout[key] = [
 ...newLayout[key], 
 {
   i: moduleData.type,
   x: (newLayout[key].length * 1) % 3,
   y: Infinity,
   w: 1,
   h: 5
 }
]; // from newLayout[key].push({DATA}); in addNewModuleInLayout

由于您在
removeModule
中使用了
filter
,因此您在那里应该很好

对。但是在
let newLayout=[…this.state.layouts]
上,我得到一个错误,因为这是一个具有数组属性的对象…很抱歉,我没有看到
layouts
是一个对象。你能通过
让newLayout={…this.state.layouts}
获得布局对象的浅层副本吗?看起来,我无法逃脱。当我尝试添加或删除模块(尝试更改状态)模块或布局时,它不会100%工作?布局更新不起作用是有道理的,因为您没有深度复制对象,因此在浅层副本上引用布局阵列时也会出现同样的问题。不过,我刚刚更新了我的评论,提出了一个解决方案。让我知道这是否奏效是的,这样各州就不同了。但这给了其他一些隐藏的问题以生命:另一个问题将接踵而至,但就这个问题而言,一切都是好的