Reputation: 777
In a dashboard for each module its layout data (using react-grid-layout) is stored separately from the module data and each of them is stored in a database. Current module data and layout data are stored in the Dashboard component state. I am trying to call separate axios POST requests inside componentDidMount()
whenever the previous state of the modules or the layouts differ from the current ones in order to save the changes in the database. But with debugging and logging, I see that prevState
equals this.state
.
Here are the methods that change the related states and the componentDidMount()
method:
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 });
}
An example of a module data and layout data for a certain module would be:
// 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" }]
Could anyone guide on what am I doing wrong here that both states are equal?
Upvotes: 2
Views: 789
Reputation: 71
try updating your array declarations in both addNewModuleInLayout
and removeModule
to
const newLayout = { ...this.state.layouts }; // from let newLayout = this.state.layouts
const newModule = [...this.state.modules]; // from let newModule = this.state.modules
in cDM you don't create a "new" copy of your module/layout arrays on state, but rather reference the arrays directly. when you update the arrays you actually mutate your state, so when you diff prevState
with this.state
the stringified versions are equal.
this won't deeply copy your layouts object though so you will run into the same issue when pushing to your layout arrays. you might be able to get around this by creating a new array when updating a layout instead of pushing
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
since you use filter
in removeModule
you should be good there
Upvotes: 2