javascript - componentDidUpdate 中的先前状态和当前状态相等

标签 javascript reactjs axios

在每个模块的仪表板中,其布局数据(使用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" }]

任何人都可以指导我在这里做错了什么,两个州都是平等的吗?

最佳答案

尝试将 addNewModuleInLayoutremoveModule 中的数组声明更新为

const newLayout = { ...this.state.layouts }; // from let newLayout = this.state.layouts
const newModule = [...this.state.modules]; // from let newModule = this.state.modules

在 cDM 中,您不会在状态上创建模块/布局数组的"new"副本,而是直接引用数组。当您更新数组时,您实际上会改变您的状态,因此当您将 prevStatethis.state 进行比较时,字符串化版本是相等的。

这不会深度复制您的布局对象,因此在推送到布局数组时您会遇到相同的问题。您可以通过在更新布局时创建新数组而不是推送来解决此问题

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,你应该可以很好地实现

关于javascript - componentDidUpdate 中的先前状态和当前状态相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56582642/

相关文章:

javascript - 使用Axios和VueJS通过id获取数据

javascript - 如何用没有变量 </script> 标签的 javascript 替换 javascript,在 Firefox 中提前结束 javascript

javascript - 两列 - 一列固定

javascript - 无法导入 Materialize CSS JS react

reactjs - 未捕获的类型错误 : Cannot read property 'history' of undefined

reactjs - 使用 axios 向 Elasticsearch 发送请求

javascript - 如何将 promise 的 XHR 转换为 async/await?

javascript - Fabric.js BlendColor 图像过滤器

reactjs - 在react-router 2.4中将props传递给路由

javascript - Axios 在 React 应用程序中请求响应 401,但在 Postman 中工作?