Ag-grid slow render after upgrade to v27 - reactjs

I recently upgraded my ag-grid v21 to 27. I'm using node 14.19 and Material-UI v4. When I set my pagination to 30 (it's ok with 10) I have a lag (~0.5sec) and when I go to the next page or if I sort my column and if I add more row to display in my pagination, e.g 100 I'll get more lag (~1sec). With ag-grid v21 I never had this lag I don't understand what I have to change to be ok with ag-grid v27. I just have 500 row in my json object. Here is my code :
import React, { Component } from "react";
import { axiosApiBackend } from "variables/axiosConfigs.jsx";
import PropTypes from "prop-types";
import { AgGridReact } from "ag-grid-react";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-material.css";
// core components
import GridContainer from "components/Grid/GridContainer.jsx";
import GridItem from "components/Grid/GridItem.jsx";
class Customer extends Component {
constructor(props) {
super(props);
this.BACKEND_URL = "/customers";
this.gridApi = null;
this.gridColumnApi = null;
this.state = {
columnDefs: [
{
headerName: "#",
field: "id",
sort: "desc",
},
{
headerName: "User",
field: "user",
valueGetter: (params) =>
(params.data.lastname || "") + " " + (params.data.firstname || ""),
},
{
headerName: "Email",
field: "email",
},
{
headerName: "Address",
field: "address",
},
{
headerName: "Zip code",
field: "city.zip",
},
{
headerName: "city",
field: "city.name",
},
],
defaultColDef: {
sortable: true,
},
data: null,
frameworkComponents: {},
};
}
componentDidMount() {
this.loadAsyncData();
}
loadAsyncData() {
axiosApiBackend.get(this.BACKEND_URL).then((result) => {
this.setState({ data: result.data }, () => {});
});
}
onGridReady = (params) => {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
};
render() {
return (
<GridContainer>
<GridItem xs={12} className="ag-theme-material">
<AgGridReact
domLayout="autoHeight"
rowData={this.state.data}
columnDefs={this.state.columnDefs}
suppressRowClickSelection={true}
groupSelectsChildren={true}
rowSelection={"multiple"}
rowGroupPanelShow={"always"}
pivotPanelShow={"always"}
enableRangeSelection={true}
pagination={true}
paginationPageSize={30}
onGridReady={this.onGridReady}
/>
</GridItem>
</GridContainer>
);
}
}
Customer.propTypes = {
location: PropTypes.any,
history: PropTypes.any,
classes: PropTypes.any,
};
export default Customer;
How can I do to fix this lag ?
Edit:
I just tried the version 26 and I don't have the lag. When I retry the version 27 I got the lag again. I don't know if this bug is related to the v27 or if I have to do something else
Edit 2:
I think the problem is related to https://www.ag-grid.com/react-data-grid/reactui/
So I tried to use the suppressReactUi=true It's a little bit better but the render with v26 is faster. So I don't know why I got the lag with the new render in the v27. Maybe I have to upgrade my react version ?

Try to turn off the React Developer Tools extension
And React in Production Mode works faster than Dev Mode

Related

trying to implement a text filter to a ag-grid in a react component

I can't figure out how to implement a simple search bar to the ag-grid i set. I would like to let my input filter the results in my grid based on every columns I couldn't figure out a good documentation with example for that. Here is my code. Feel free to redirect me to a proper example or another question similar.
import React from 'react';
import { AgGridReact } from 'ag-grid-react';
import axios from 'axios';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
class ListTableClients extends React.Component {
constructor(props) {
super(props);
this.state = {
defaultColDef: {
flex: 1,
cellClass: 'cell-wrap-text',
autoHeight: true,
sortable: true,
resizable: true,
},
columnDefs: [
{ headerName: "id", field: "id", maxWidth: 100 },
{ headerName: "name", field: "name"},
{ headerName: "email", field: "email"}],
rowData: [
{ id: 1, name: 'maison du café', email: 'maisonducafe#gamil.com' },
{ id: 2, name: 'Warehouse', email: 'contact#warehouse.fr' },
{ id: 3, name: 'Maestro', email: 'maestro#gmail.com' }],
rowHeight: 275,
}
}
componentDidMount() {
console.log('test');
axios.get('http://localhost:8080/listClients').then((res) => {
this.setState({ rowData: res.data });
}).catch((error) => { console.log(error) });
}
render() {
return (
<div style={{width: '100%', paddingLeft: '50px', paddingRight: '50px', paddingTop: '50px'}} className="ag-theme-alpine">
<input type="text" placeholder="Filter..." onInput={this.onFilterTextBoxChanged}/>
<AgGridReact
domLayout='autoHeight'
columnDefs={this.state.columnDefs}
defaultColDef={this.state.defaultColDef}
getRowHeight={this.state.getRowHeight}
rowData={this.state.rowData}>
</AgGridReact>
</div>
);
}
}
export default ListTableClients;
Refer this demo
If the cell data in object format then you have to format it Ag-Grid Value Formatters

Making an API call through ReactJs, fetch JSON and display in ag-grid

EDIT:
I have experimented around the code. The modified code is given below.
Now I get an error "TypeError: rowData.forEach is not a function" in the browser.
When I console log, enter image description here it is showing the JSON arrays (I have attached a screenshot).
I think the problem is something to do with JSON object not getting converted to an array. Can someone experienced, please help?
MODIFIED CODE
import React, { Component } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';
//import {Grid} from '#ag-grid-community/all-modules';
class App extends Component {
constructor (props)
{
super(props);
this.state={
isLoaded: true,
columnDefs: [{
headerName: "Id", field: "id"
}, {
headerName: "Name", field: "name"
}, {
headerName: "Description", field: "description"
}, {
headerName: "Price", field: "price"
},
{
headerName: "Firm Name", field: "category_id"
},
{
headerName: "Amount", field: "category_name"
}
],
rowData: []
};
}
componentDidMount()
{
console.log ("entered");
fetch("http://localhost/api/product/read.php")
.then (res => res.json() )
//.then ((result) => {this.setState({rowData: result, isLoaded: true})},
.then(rowData => this.setState({rowData}),
(error) => {
console.log("error");
this.setState({
isLoaded: false,
error
});
}
)
}
render() {
const {error,isLoaded,rowData } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
}
else if (!isLoaded) {
return <div>Loading...</div>;
}
else {
console.log({rowData});
return (
<div
className="ag-theme-balham"
style={
{
height: '800px',
width: '1200px' }
}
>
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
>
</AgGridReact>
</div>
);
}
}
}
export default App;
I have been trying to call an API from reactjs.I have tried fetch,jquery and apiox codes but I am getting an error. I actually want to call an external URL from one of our other software but since it is not working, I have created a php file on localhost and tried calling that file.In each case it is printing "entered" and then "error" to console.
Both the external api file and the localhost file, when tried in the browser are returning JSON objects.
PLease see code below.
import React, { Component } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';
class ListOrders extends Component {
constructor(props) {
super(props);
this.state = {
columnDefs: [{
headerName: "Invoice No", field: "id"
}, {
headerName: "Invoice Date", field: "name"
}, {
headerName: "Payer Name", field: "description"
}, {
headerNAme: "Ship To Name", field: "price"
},
{
headerNAme: "Firm Name", field: "category_id"
},
{
headerNAme: "Amount", field: "category_name"
}
],
rowData: []
};
}
componentDidMount()
{
console.log ("entered");
fetch("http://localhost/api/product/read.php",{
mode: "no-cors",
method: 'GET', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
// body: JSON.stringify(),
})
.then(response => response.json())
.then(
(response) => {
console.log("result");
this.setState( {
rowData: response.JSON
//console.log(rowData)
});
},
(error) => {
console.log("error");
this.setState({
isLoaded: true,
error
});
}
)
}
render()
{
return (
<div
className="ag-theme-balham"
style={
{
height: '800px',
width: '1200px' }
}
>
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}>
</AgGridReact>
</div>
);
}
}
export default ListOrders ;

Highcharts not rendering : React+Typescript+Highcharts

Trying to bring up a highchart using react. I am having multiple fetch api calls(for illustration, I have added only 2) whose data I will be using to render something in the UI.
In this example data1 is used to render a table, data2 is used to render a highchart.
I am storing the outputs of these calls in a state object. When I am calling these API's, I am getting the data but unable to set it to "series" property of highcharts for rendering, as a result nothing is getting rendered.
Structure of the data I am fetching
"api2" : [
{
"name" : "Test1",
"value" : 12
},
{
"name" : "Test2",
"value" : 9
}
]
Can someone help me with this? Where am I going wrong?
I am using highcharts-react-official for this
Code
import * as React from 'react';
import Highcharts from 'highcharts'
import HighchartsReact from 'highcharts-react-official';
interface IState {
data1: [];
data2: [];
}
interface IProps {}
class Example extends React.Component<IProps,IState> {
constructor(props:any)
{
super(props);
this.state = {
data1: [],
data2: []
}
}
componentDidMount()
{
Promise.all([
fetch('http://localhost:3001/api1'),
fetch('http://localhost:3001/api2')
])
.then(([res1, res2]) => Promise.all([res1.json(), res2.json()]))
.then(([data1, data2]) => this.setState({
data1: data1,
data2: data2
}));
}
render() {
let options:any;
options = {
chart: {
type: 'column'
},
credits: false,
exporting: {enabled: false},
title: {
text: ''
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'bottom'
},
xAxis: {
visible:false
},
yAxis: {
visible:false
},
plotOptions: {
column: {
dataLabels: {
enabled: true }
}
},
series: this.state.data2
};
return(
<div className="an-content">
//some table rendering will happen here
<HighchartsReact
highcharts={Highcharts}
options={options}
/>
</div>
)
}
}
export default Example;
You need to provide the data format required by Highcharts:
this.setState({
data2: data2.map(x => ({ name: x.name, data: [x.value] }))
});
Live demo: https://codesandbox.io/s/7w2pw4p900
API Reference: https://api.highcharts.com/highcharts/series.column.data

How to wrap ag-grid-react into component?

I'm using React with Redux. I have a table which is made with ag-grid for react.
Table data can be edited in line and saved.
How to create wrapper component for that table? I need to have multiple tables with same functionality just with different data.
In ag-grid documentation it shows how to implement with redux store and reducers, but this solution only works with one table, because we have only one state per app. I don't want to dublicate my code just because i have two different lists of data...
Here's a quick example
// Grid.jsx
import React, {
PureComponent,
} from 'react';
import {
AgGridReact,
} from 'ag-grid-react';
class Grid extends PureComponent {
state = {
columnDefs : [],
rowData : []
};
/**
* This will set your internal columnDefs & rowData
* from the props being passed in
* <Grid columnDefs={columnDefs} rowData={rowData} />
*/
static getDerivedStateFromProps(nextProps) {
const {
columnDefs,
rowData,
} = nextProps;
return {
columnDefs,
rowData,
};
}
render() {
const {
columnDefs,
rowData,
} = this.state;
return (
<AgGridReact
columnDefs={columnDefs}
rowData={rowData}
/>
);
}
}
export default Grid;
// ExampleImpl.jsx
import Grid from './Grid';
class ExampleImpl extends PureComponent {
render() {
// Assuming you got these from the connect
const rowData: [
{
name: "Ireland",
continent: "Europe",
language: "English",
code: "ie",
population: 4000000,
summary: "Master Drinkers"
},
];
const columnDefs: [
{
headerName: "Name",
field: "name",
cellRenderer: countryCellRenderer
},
{
headerName: "Continent",
field: "continent",
width: 150
},
{
headerName: "Language",
field: "language",
width: 150
}
];
return <Grid
rowData = {rowData}
columnDefs = {columnDefs}
/>
}
}
export default connect(ExampleImpl);
// ExampleImplII.jsx
import Grid from './Grid';
class ExampleImplII extends PureComponent {
render() {
// Assuming you got these from connect
const rowData: [
{
name: "Ireland",
continent: "Europe",
language: "English",
code: "ie",
population: 4000000,
summary: "Master Drinkers"
},
];
const columnDefs: [
{
headerName: "Name",
field: "name",
cellRenderer: countryCellRenderer
},
{
headerName: "Continent",
field: "continent",
width: 150
},
{
headerName: "Language",
field: "language",
width: 150
}
];
return <Grid
rowData={rowData}
columnDefs={columnDefs}
/>
}
}
export default connect(ExampleImplII);
This way you have 1 presentational component and 2 container components (smart components) which know how to fetch the data and just pass it to your presentational component.

devextreame use in reactjs

I want to use data grid devextreme in react.
I have tried this code but when i run my project i have this error : jQuery is not defined.
when i try to import jquery i still have the error.
import React, {Component} from 'react';
import dxDataGrid from '../../node_modules/devextreme/dist/js/dx.all';
class Grid extends Component {
constructor() {
super();
this.state = {
dataSource: employees,
sorting: {
mode: "multiple"
},
columns: [
{
dataField: "Prefix",
caption: "Title",
width: 70
}, {
dataField: "FirstName",
sortOrder: "asc"
}, {
dataField: "LastName",
sortOrder: "asc"
}, "City",
"State", {
dataField: "Position",
width: 130
}, {
dataField: "HireDate",
dataType: "date"
}
]
}
}
render () {
return (
<div>
<Grid value= "false" text= "Disable Sorting for the Position Column"/>
</div>
)
}
}
export default Grid;

Resources