I want to use mobx store for state management. I want to update record in the store and it should be reflected in the grid. I have method updateRecord which is updating the store but the AGgrid does not get updated. Another method deleteRecord works perfectly fine and it updates store as well as grid.
I have tried two ways to update the store but none of this works.
this.gridData[index] = { id: 1, name: 'XX John' } //update the complete object
this.gridData[index].name = 'XX John'; // update specific property of object
How to make updateRecord method work ? Please provide any pointers.
Complete Source Code.
import React, { useState } from 'react';
import { observable, action, makeAutoObservable } from 'mobx';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { observer } from 'mobx-react-lite';
interface IEmployee {
id: number;
name: string;
}
class MyStore {
gridData: IEmployee[] = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
];
constructor() {
makeAutoObservable(this, {
gridData: observable,
updateRecord: action,
deleteRecord: action
});
}
updateRecord(id: number, newData: { name: string }) {
const index = this.gridData.findIndex((record) => record.id === id);
//this.gridData[index] = { id: 1, name: 'XX John' }
//this.gridData[index].name = 'XX John';
}
deleteRecord(id: number) {
this.gridData = this.gridData.filter((record) => record.id !== id);
}
}
const store = new MyStore();
const MyComponent = observer(() => {
const [colDefs, setColDefs] = useState([{ field: 'id' }, { field: 'name' }]);
const { gridData } = store;
return (
<div>
<div className="ag-theme-alpine" style={{ height: 400, width: 600 }}>
<AgGridReact rowData={gridData} columnDefs={colDefs}></AgGridReact>
</div>
<button onClick={() => store.updateRecord(1, { name: 'Updated John' })}>
Update record
</button>
<button onClick={() => store.deleteRecord(2)}>Delete record</button>
</div>
);
})
AgGridReact
probably only updates when rowData
(gridData
) changes entirely (changes reference), it probably can't know that just some property of some inner object was updated.
I think the easiest way would be to just use toJS
(https://mobx.js.org/api.html#tojs) MobX method to transform your observable value to regular JS object.
<AgGridReact rowData={toJS(gridData)} columnDefs={colDefs}></AgGridReact>
Your deleteRecord
method works because you create new gridData
array by using .filter()