Stateful Grid

Stateful components are class components that have a state which gets initialized in the constructor.

You can configure a stateful KendoReact Grid to perform paging, sorting, filtering, grouping, and editing, and also reuse it in multiple applications and pages by setting its columns and desired data operations.

import React from 'react';
import ReactDOM from 'react-dom';

import { GridWithState as Grid } from './with-state.jsx';
import { GridColumn } from '@progress/kendo-react-grid';

import products from './products.json';

class App extends React.PureComponent {
    render() {
        return (
            <div>
                <Grid
                    data={products}
                    style={{ height: '540px' }}
                    sortable={true}
                    pageSize={10}
                    pageable={true}
                    groupable={true}
                    filterable={true}
                    reorderable={true}
                    resizable={true}
                >
                    <GridColumn field="ProductName" title="Product Name" />
                    <GridColumn field="UnitsInStock" title="Units" filter="numeric" editor="numeric" />
                </Grid>
            </div>
        );
    }
}

ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);
[{
    "ProductID" : 1,
    "ProductName" : "Chai",
    "SupplierID" : 1,
    "CategoryID" : 1,
    "QuantityPerUnit" : "10 boxes x 20 bags",
    "UnitPrice" : 18.0000,
    "UnitsInStock" : 39,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 10,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 2,
    "ProductName" : "Chang",
    "SupplierID" : 1,
    "CategoryID" : 1,
    "QuantityPerUnit" : "24 - 12 oz bottles",
    "UnitPrice" : 19.0000,
    "UnitsInStock" : 17,
    "UnitsOnOrder" : 40,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 3,
    "ProductName" : "Aniseed Syrup",
    "SupplierID" : 1,
    "CategoryID" : 2,
    "QuantityPerUnit" : "12 - 550 ml bottles",
    "UnitPrice" : 10.0000,
    "UnitsInStock" : 13,
    "UnitsOnOrder" : 70,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 4,
    "ProductName" : "Chef Anton's Cajun Seasoning",
    "SupplierID" : 2,
    "CategoryID" : 2,
    "QuantityPerUnit" : "48 - 6 oz jars",
    "UnitPrice" : 22.0000,
    "UnitsInStock" : 53,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 5,
    "ProductName" : "Chef Anton's Gumbo Mix",
    "SupplierID" : 2,
    "CategoryID" : 2,
    "QuantityPerUnit" : "36 boxes",
    "UnitPrice" : 21.3500,
    "UnitsInStock" : 0,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : true,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 6,
    "ProductName" : "Grandma's Boysenberry Spread",
    "SupplierID" : 3,
    "CategoryID" : 2,
    "QuantityPerUnit" : "12 - 8 oz jars",
    "UnitPrice" : 25.0000,
    "UnitsInStock" : 120,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 7,
    "ProductName" : "Uncle Bob's Organic Dried Pears",
    "SupplierID" : 3,
    "CategoryID" : 7,
    "QuantityPerUnit" : "12 - 1 lb pkgs.",
    "UnitPrice" : 30.0000,
    "UnitsInStock" : 15,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 10,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 7,
        "CategoryName" : "Produce",
        "Description" : "Dried fruit and bean curd"
    }
}, {
    "ProductID" : 8,
    "ProductName" : "Northwoods Cranberry Sauce",
    "SupplierID" : 3,
    "CategoryID" : 2,
    "QuantityPerUnit" : "12 - 12 oz jars",
    "UnitPrice" : 40.0000,
    "UnitsInStock" : 6,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 9,
    "ProductName" : "Mishi Kobe Niku",
    "SupplierID" : 4,
    "CategoryID" : 6,
    "QuantityPerUnit" : "18 - 500 g pkgs.",
    "UnitPrice" : 97.0000,
    "UnitsInStock" : 29,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : true,
    "Category" : {
        "CategoryID" : 6,
        "CategoryName" : "Meat/Poultry",
        "Description" : "Prepared meats"
    }
}, {
    "ProductID" : 10,
    "ProductName" : "Ikura",
    "SupplierID" : 4,
    "CategoryID" : 8,
    "QuantityPerUnit" : "12 - 200 ml jars",
    "UnitPrice" : 31.0000,
    "UnitsInStock" : 31,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 11,
    "ProductName" : "Queso Cabrales",
    "SupplierID" : 5,
    "CategoryID" : 4,
    "QuantityPerUnit" : "1 kg pkg.",
    "UnitPrice" : 21.0000,
    "UnitsInStock" : 22,
    "UnitsOnOrder" : 30,
    "ReorderLevel" : 30,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 12,
    "ProductName" : "Queso Manchego La Pastora",
    "SupplierID" : 5,
    "CategoryID" : 4,
    "QuantityPerUnit" : "10 - 500 g pkgs.",
    "UnitPrice" : 38.0000,
    "UnitsInStock" : 86,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 13,
    "ProductName" : "Konbu",
    "SupplierID" : 6,
    "CategoryID" : 8,
    "QuantityPerUnit" : "2 kg box",
    "UnitPrice" : 6.0000,
    "UnitsInStock" : 24,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 5,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 14,
    "ProductName" : "Tofu",
    "SupplierID" : 6,
    "CategoryID" : 7,
    "QuantityPerUnit" : "40 - 100 g pkgs.",
    "UnitPrice" : 23.2500,
    "UnitsInStock" : 35,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 7,
        "CategoryName" : "Produce",
        "Description" : "Dried fruit and bean curd"
    }
}, {
    "ProductID" : 15,
    "ProductName" : "Genen Shouyu",
    "SupplierID" : 6,
    "CategoryID" : 2,
    "QuantityPerUnit" : "24 - 250 ml bottles",
    "UnitPrice" : 15.5000,
    "UnitsInStock" : 39,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 5,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 16,
    "ProductName" : "Pavlova",
    "SupplierID" : 7,
    "CategoryID" : 3,
    "QuantityPerUnit" : "32 - 500 g boxes",
    "UnitPrice" : 17.4500,
    "UnitsInStock" : 29,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 10,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 17,
    "ProductName" : "Alice Mutton",
    "SupplierID" : 7,
    "CategoryID" : 6,
    "QuantityPerUnit" : "20 - 1 kg tins",
    "UnitPrice" : 39.0000,
    "UnitsInStock" : 0,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : true,
    "Category" : {
        "CategoryID" : 6,
        "CategoryName" : "Meat/Poultry",
        "Description" : "Prepared meats"
    }
}, {
    "ProductID" : 18,
    "ProductName" : "Carnarvon Tigers",
    "SupplierID" : 7,
    "CategoryID" : 8,
    "QuantityPerUnit" : "16 kg pkg.",
    "UnitPrice" : 62.5000,
    "UnitsInStock" : 42,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 19,
    "ProductName" : "Teatime Chocolate Biscuits",
    "SupplierID" : 8,
    "CategoryID" : 3,
    "QuantityPerUnit" : "10 boxes x 12 pieces",
    "UnitPrice" : 9.2000,
    "UnitsInStock" : 25,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 5,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 20,
    "ProductName" : "Sir Rodney's Marmalade",
    "SupplierID" : 8,
    "CategoryID" : 3,
    "QuantityPerUnit" : "30 gift boxes",
    "UnitPrice" : 81.0000,
    "UnitsInStock" : 40,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 21,
    "ProductName" : "Sir Rodney's Scones",
    "SupplierID" : 8,
    "CategoryID" : 3,
    "QuantityPerUnit" : "24 pkgs. x 4 pieces",
    "UnitPrice" : 10.0000,
    "UnitsInStock" : 3,
    "UnitsOnOrder" : 40,
    "ReorderLevel" : 5,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 22,
    "ProductName" : "Gustaf's Knäckebröd",
    "SupplierID" : 9,
    "CategoryID" : 5,
    "QuantityPerUnit" : "24 - 500 g pkgs.",
    "UnitPrice" : 21.0000,
    "UnitsInStock" : 104,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 5,
        "CategoryName" : "Grains/Cereals",
        "Description" : "Breads, crackers, pasta, and cereal"
    }
}, {
    "ProductID" : 23,
    "ProductName" : "Tunnbröd",
    "SupplierID" : 9,
    "CategoryID" : 5,
    "QuantityPerUnit" : "12 - 250 g pkgs.",
    "UnitPrice" : 9.0000,
    "UnitsInStock" : 61,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 5,
        "CategoryName" : "Grains/Cereals",
        "Description" : "Breads, crackers, pasta, and cereal"
    }
}, {
    "ProductID" : 24,
    "ProductName" : "Guaraná Fantástica",
    "SupplierID" : 10,
    "CategoryID" : 1,
    "QuantityPerUnit" : "12 - 355 ml cans",
    "UnitPrice" : 4.5000,
    "UnitsInStock" : 20,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : true,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 25,
    "ProductName" : "NuNuCa Nuß-Nougat-Creme",
    "SupplierID" : 11,
    "CategoryID" : 3,
    "QuantityPerUnit" : "20 - 450 g glasses",
    "UnitPrice" : 14.0000,
    "UnitsInStock" : 76,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 30,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 26,
    "ProductName" : "Gumbär Gummibärchen",
    "SupplierID" : 11,
    "CategoryID" : 3,
    "QuantityPerUnit" : "100 - 250 g bags",
    "UnitPrice" : 31.2300,
    "UnitsInStock" : 15,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 27,
    "ProductName" : "Schoggi Schokolade",
    "SupplierID" : 11,
    "CategoryID" : 3,
    "QuantityPerUnit" : "100 - 100 g pieces",
    "UnitPrice" : 43.9000,
    "UnitsInStock" : 49,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 30,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 28,
    "ProductName" : "Rössle Sauerkraut",
    "SupplierID" : 12,
    "CategoryID" : 7,
    "QuantityPerUnit" : "25 - 825 g cans",
    "UnitPrice" : 45.6000,
    "UnitsInStock" : 26,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : true,
    "Category" : {
        "CategoryID" : 7,
        "CategoryName" : "Produce",
        "Description" : "Dried fruit and bean curd"
    }
}, {
    "ProductID" : 29,
    "ProductName" : "Thüringer Rostbratwurst",
    "SupplierID" : 12,
    "CategoryID" : 6,
    "QuantityPerUnit" : "50 bags x 30 sausgs.",
    "UnitPrice" : 123.7900,
    "UnitsInStock" : 0,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : true,
    "Category" : {
        "CategoryID" : 6,
        "CategoryName" : "Meat/Poultry",
        "Description" : "Prepared meats"
    }
}, {
    "ProductID" : 30,
    "ProductName" : "Nord-Ost Matjeshering",
    "SupplierID" : 13,
    "CategoryID" : 8,
    "QuantityPerUnit" : "10 - 200 g glasses",
    "UnitPrice" : 25.8900,
    "UnitsInStock" : 10,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 31,
    "ProductName" : "Gorgonzola Telino",
    "SupplierID" : 14,
    "CategoryID" : 4,
    "QuantityPerUnit" : "12 - 100 g pkgs",
    "UnitPrice" : 12.5000,
    "UnitsInStock" : 0,
    "UnitsOnOrder" : 70,
    "ReorderLevel" : 20,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 32,
    "ProductName" : "Mascarpone Fabioli",
    "SupplierID" : 14,
    "CategoryID" : 4,
    "QuantityPerUnit" : "24 - 200 g pkgs.",
    "UnitPrice" : 32.0000,
    "UnitsInStock" : 9,
    "UnitsOnOrder" : 40,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 33,
    "ProductName" : "Geitost",
    "SupplierID" : 15,
    "CategoryID" : 4,
    "QuantityPerUnit" : "500 g",
    "UnitPrice" : 2.5000,
    "UnitsInStock" : 112,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 20,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 34,
    "ProductName" : "Sasquatch Ale",
    "SupplierID" : 16,
    "CategoryID" : 1,
    "QuantityPerUnit" : "24 - 12 oz bottles",
    "UnitPrice" : 14.0000,
    "UnitsInStock" : 111,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 35,
    "ProductName" : "Steeleye Stout",
    "SupplierID" : 16,
    "CategoryID" : 1,
    "QuantityPerUnit" : "24 - 12 oz bottles",
    "UnitPrice" : 18.0000,
    "UnitsInStock" : 20,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 36,
    "ProductName" : "Inlagd Sill",
    "SupplierID" : 17,
    "CategoryID" : 8,
    "QuantityPerUnit" : "24 - 250 g  jars",
    "UnitPrice" : 19.0000,
    "UnitsInStock" : 112,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 20,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 37,
    "ProductName" : "Gravad lax",
    "SupplierID" : 17,
    "CategoryID" : 8,
    "QuantityPerUnit" : "12 - 500 g pkgs.",
    "UnitPrice" : 26.0000,
    "UnitsInStock" : 11,
    "UnitsOnOrder" : 50,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 38,
    "ProductName" : "Côte de Blaye",
    "SupplierID" : 18,
    "CategoryID" : 1,
    "QuantityPerUnit" : "12 - 75 cl bottles",
    "UnitPrice" : 263.5000,
    "UnitsInStock" : 17,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 39,
    "ProductName" : "Chartreuse verte",
    "SupplierID" : 18,
    "CategoryID" : 1,
    "QuantityPerUnit" : "750 cc per bottle",
    "UnitPrice" : 18.0000,
    "UnitsInStock" : 69,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 5,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 40,
    "ProductName" : "Boston Crab Meat",
    "SupplierID" : 19,
    "CategoryID" : 8,
    "QuantityPerUnit" : "24 - 4 oz tins",
    "UnitPrice" : 18.4000,
    "UnitsInStock" : 123,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 30,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 41,
    "ProductName" : "Jack's New England Clam Chowder",
    "SupplierID" : 19,
    "CategoryID" : 8,
    "QuantityPerUnit" : "12 - 12 oz cans",
    "UnitPrice" : 9.6500,
    "UnitsInStock" : 85,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 10,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 42,
    "ProductName" : "Singaporean Hokkien Fried Mee",
    "SupplierID" : 20,
    "CategoryID" : 5,
    "QuantityPerUnit" : "32 - 1 kg pkgs.",
    "UnitPrice" : 14.0000,
    "UnitsInStock" : 26,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : true,
    "Category" : {
        "CategoryID" : 5,
        "CategoryName" : "Grains/Cereals",
        "Description" : "Breads, crackers, pasta, and cereal"
    }
}, {
    "ProductID" : 43,
    "ProductName" : "Ipoh Coffee",
    "SupplierID" : 20,
    "CategoryID" : 1,
    "QuantityPerUnit" : "16 - 500 g tins",
    "UnitPrice" : 46.0000,
    "UnitsInStock" : 17,
    "UnitsOnOrder" : 10,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 44,
    "ProductName" : "Gula Malacca",
    "SupplierID" : 20,
    "CategoryID" : 2,
    "QuantityPerUnit" : "20 - 2 kg bags",
    "UnitPrice" : 19.4500,
    "UnitsInStock" : 27,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 45,
    "ProductName" : "Rogede sild",
    "SupplierID" : 21,
    "CategoryID" : 8,
    "QuantityPerUnit" : "1k pkg.",
    "UnitPrice" : 9.5000,
    "UnitsInStock" : 5,
    "UnitsOnOrder" : 70,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 46,
    "ProductName" : "Spegesild",
    "SupplierID" : 21,
    "CategoryID" : 8,
    "QuantityPerUnit" : "4 - 450 g glasses",
    "UnitPrice" : 12.0000,
    "UnitsInStock" : 95,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 47,
    "ProductName" : "Zaanse koeken",
    "SupplierID" : 22,
    "CategoryID" : 3,
    "QuantityPerUnit" : "10 - 4 oz boxes",
    "UnitPrice" : 9.5000,
    "UnitsInStock" : 36,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 48,
    "ProductName" : "Chocolade",
    "SupplierID" : 22,
    "CategoryID" : 3,
    "QuantityPerUnit" : "10 pkgs.",
    "UnitPrice" : 12.7500,
    "UnitsInStock" : 15,
    "UnitsOnOrder" : 70,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 49,
    "ProductName" : "Maxilaku",
    "SupplierID" : 23,
    "CategoryID" : 3,
    "QuantityPerUnit" : "24 - 50 g pkgs.",
    "UnitPrice" : 20.0000,
    "UnitsInStock" : 10,
    "UnitsOnOrder" : 60,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 50,
    "ProductName" : "Valkoinen suklaa",
    "SupplierID" : 23,
    "CategoryID" : 3,
    "QuantityPerUnit" : "12 - 100 g bars",
    "UnitPrice" : 16.2500,
    "UnitsInStock" : 65,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 30,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 51,
    "ProductName" : "Manjimup Dried Apples",
    "SupplierID" : 24,
    "CategoryID" : 7,
    "QuantityPerUnit" : "50 - 300 g pkgs.",
    "UnitPrice" : 53.0000,
    "UnitsInStock" : 20,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 10,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 7,
        "CategoryName" : "Produce",
        "Description" : "Dried fruit and bean curd"
    }
}, {
    "ProductID" : 52,
    "ProductName" : "Filo Mix",
    "SupplierID" : 24,
    "CategoryID" : 5,
    "QuantityPerUnit" : "16 - 2 kg boxes",
    "UnitPrice" : 7.0000,
    "UnitsInStock" : 38,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 5,
        "CategoryName" : "Grains/Cereals",
        "Description" : "Breads, crackers, pasta, and cereal"
    }
}, {
    "ProductID" : 53,
    "ProductName" : "Perth Pasties",
    "SupplierID" : 24,
    "CategoryID" : 6,
    "QuantityPerUnit" : "48 pieces",
    "UnitPrice" : 32.8000,
    "UnitsInStock" : 0,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : true,
    "Category" : {
        "CategoryID" : 6,
        "CategoryName" : "Meat/Poultry",
        "Description" : "Prepared meats"
    }
}, {
    "ProductID" : 54,
    "ProductName" : "Tourtière",
    "SupplierID" : 25,
    "CategoryID" : 6,
    "QuantityPerUnit" : "16 pies",
    "UnitPrice" : 7.4500,
    "UnitsInStock" : 21,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 10,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 6,
        "CategoryName" : "Meat/Poultry",
        "Description" : "Prepared meats"
    }
}, {
    "ProductID" : 55,
    "ProductName" : "Pâté chinois",
    "SupplierID" : 25,
    "CategoryID" : 6,
    "QuantityPerUnit" : "24 boxes x 2 pies",
    "UnitPrice" : 24.0000,
    "UnitsInStock" : 115,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 20,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 6,
        "CategoryName" : "Meat/Poultry",
        "Description" : "Prepared meats"
    }
}, {
    "ProductID" : 56,
    "ProductName" : "Gnocchi di nonna Alice",
    "SupplierID" : 26,
    "CategoryID" : 5,
    "QuantityPerUnit" : "24 - 250 g pkgs.",
    "UnitPrice" : 38.0000,
    "UnitsInStock" : 21,
    "UnitsOnOrder" : 10,
    "ReorderLevel" : 30,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 5,
        "CategoryName" : "Grains/Cereals",
        "Description" : "Breads, crackers, pasta, and cereal"
    }
}, {
    "ProductID" : 57,
    "ProductName" : "Ravioli Angelo",
    "SupplierID" : 26,
    "CategoryID" : 5,
    "QuantityPerUnit" : "24 - 250 g pkgs.",
    "UnitPrice" : 19.5000,
    "UnitsInStock" : 36,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 20,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 5,
        "CategoryName" : "Grains/Cereals",
        "Description" : "Breads, crackers, pasta, and cereal"
    }
}, {
    "ProductID" : 58,
    "ProductName" : "Escargots de Bourgogne",
    "SupplierID" : 27,
    "CategoryID" : 8,
    "QuantityPerUnit" : "24 pieces",
    "UnitPrice" : 13.2500,
    "UnitsInStock" : 62,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 20,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 59,
    "ProductName" : "Raclette Courdavault",
    "SupplierID" : 28,
    "CategoryID" : 4,
    "QuantityPerUnit" : "5 kg pkg.",
    "UnitPrice" : 55.0000,
    "UnitsInStock" : 79,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 60,
    "ProductName" : "Camembert Pierrot",
    "SupplierID" : 28,
    "CategoryID" : 4,
    "QuantityPerUnit" : "15 - 300 g rounds",
    "UnitPrice" : 34.0000,
    "UnitsInStock" : 19,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 61,
    "ProductName" : "Sirop d'érable",
    "SupplierID" : 29,
    "CategoryID" : 2,
    "QuantityPerUnit" : "24 - 500 ml bottles",
    "UnitPrice" : 28.5000,
    "UnitsInStock" : 113,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 62,
    "ProductName" : "Tarte au sucre",
    "SupplierID" : 29,
    "CategoryID" : 3,
    "QuantityPerUnit" : "48 pies",
    "UnitPrice" : 49.3000,
    "UnitsInStock" : 17,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 63,
    "ProductName" : "Vegie-spread",
    "SupplierID" : 7,
    "CategoryID" : 2,
    "QuantityPerUnit" : "15 - 625 g jars",
    "UnitPrice" : 43.9000,
    "UnitsInStock" : 24,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 5,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 64,
    "ProductName" : "Wimmers gute Semmelknödel",
    "SupplierID" : 12,
    "CategoryID" : 5,
    "QuantityPerUnit" : "20 bags x 4 pieces",
    "UnitPrice" : 33.2500,
    "UnitsInStock" : 22,
    "UnitsOnOrder" : 80,
    "ReorderLevel" : 30,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 5,
        "CategoryName" : "Grains/Cereals",
        "Description" : "Breads, crackers, pasta, and cereal"
    }
}, {
    "ProductID" : 65,
    "ProductName" : "Louisiana Fiery Hot Pepper Sauce",
    "SupplierID" : 2,
    "CategoryID" : 2,
    "QuantityPerUnit" : "32 - 8 oz bottles",
    "UnitPrice" : 21.0500,
    "UnitsInStock" : 76,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 66,
    "ProductName" : "Louisiana Hot Spiced Okra",
    "SupplierID" : 2,
    "CategoryID" : 2,
    "QuantityPerUnit" : "24 - 8 oz jars",
    "UnitPrice" : 17.0000,
    "UnitsInStock" : 4,
    "UnitsOnOrder" : 100,
    "ReorderLevel" : 20,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}, {
    "ProductID" : 67,
    "ProductName" : "Laughing Lumberjack Lager",
    "SupplierID" : 16,
    "CategoryID" : 1,
    "QuantityPerUnit" : "24 - 12 oz bottles",
    "UnitPrice" : 14.0000,
    "UnitsInStock" : 52,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 10,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 68,
    "ProductName" : "Scottish Longbreads",
    "SupplierID" : 8,
    "CategoryID" : 3,
    "QuantityPerUnit" : "10 boxes x 8 pieces",
    "UnitPrice" : 12.5000,
    "UnitsInStock" : 6,
    "UnitsOnOrder" : 10,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 3,
        "CategoryName" : "Confections",
        "Description" : "Desserts, candies, and sweet breads"
    }
}, {
    "ProductID" : 69,
    "ProductName" : "Gudbrandsdalsost",
    "SupplierID" : 15,
    "CategoryID" : 4,
    "QuantityPerUnit" : "10 kg pkg.",
    "UnitPrice" : 36.0000,
    "UnitsInStock" : 26,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 70,
    "ProductName" : "Outback Lager",
    "SupplierID" : 7,
    "CategoryID" : 1,
    "QuantityPerUnit" : "24 - 355 ml bottles",
    "UnitPrice" : 15.0000,
    "UnitsInStock" : 15,
    "UnitsOnOrder" : 10,
    "ReorderLevel" : 30,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 71,
    "ProductName" : "Flotemysost",
    "SupplierID" : 15,
    "CategoryID" : 4,
    "QuantityPerUnit" : "10 - 500 g pkgs.",
    "UnitPrice" : 21.5000,
    "UnitsInStock" : 26,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 72,
    "ProductName" : "Mozzarella di Giovanni",
    "SupplierID" : 14,
    "CategoryID" : 4,
    "QuantityPerUnit" : "24 - 200 g pkgs.",
    "UnitPrice" : 34.8000,
    "UnitsInStock" : 14,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 0,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 4,
        "CategoryName" : "Dairy Products",
        "Description" : "Cheeses"
    }
}, {
    "ProductID" : 73,
    "ProductName" : "Röd Kaviar",
    "SupplierID" : 17,
    "CategoryID" : 8,
    "QuantityPerUnit" : "24 - 150 g jars",
    "UnitPrice" : 15.0000,
    "UnitsInStock" : 101,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 5,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 8,
        "CategoryName" : "Seafood",
        "Description" : "Seaweed and fish"
    }
}, {
    "ProductID" : 74,
    "ProductName" : "Longlife Tofu",
    "SupplierID" : 4,
    "CategoryID" : 7,
    "QuantityPerUnit" : "5 kg pkg.",
    "UnitPrice" : 10.0000,
    "UnitsInStock" : 4,
    "UnitsOnOrder" : 20,
    "ReorderLevel" : 5,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 7,
        "CategoryName" : "Produce",
        "Description" : "Dried fruit and bean curd"
    }
}, {
    "ProductID" : 75,
    "ProductName" : "Rhönbräu Klosterbier",
    "SupplierID" : 12,
    "CategoryID" : 1,
    "QuantityPerUnit" : "24 - 0.5 l bottles",
    "UnitPrice" : 7.7500,
    "UnitsInStock" : 125,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 25,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 76,
    "ProductName" : "Lakkalikööri",
    "SupplierID" : 23,
    "CategoryID" : 1,
    "QuantityPerUnit" : "500 ml",
    "UnitPrice" : 18.0000,
    "UnitsInStock" : 57,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 20,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 1,
        "CategoryName" : "Beverages",
        "Description" : "Soft drinks, coffees, teas, beers, and ales"
    }
}, {
    "ProductID" : 77,
    "ProductName" : "Original Frankfurter grüne Soße",
    "SupplierID" : 12,
    "CategoryID" : 2,
    "QuantityPerUnit" : "12 boxes",
    "UnitPrice" : 13.0000,
    "UnitsInStock" : 32,
    "UnitsOnOrder" : 0,
    "ReorderLevel" : 15,
    "Discontinued" : false,
    "Category" : {
        "CategoryID" : 2,
        "CategoryName" : "Condiments",
        "Description" : "Sweet and savory sauces, relishes, spreads, and seasonings"
    }
}]
import React from 'react';
import { GridCell } from '@progress/kendo-react-grid';

export class CommandCell extends GridCell {
    buttonClick = (e, command) => {
        this.props.onChange({ dataItem: this.props.dataItem, e, field: this.props.field, value: command });
    }

    render() {
        if (this.props.rowType !== "data") {
            return null;
        }

        if (this.props.dataItem[this.props.field]) {
            return (
                <td>
                    <button
                        className="k-button k-grid-save-command"
                        onClick={(e) => this.buttonClick(e, false)}
                    > Close
                    </button>
                </td>
            );
        }

        return (
            <td>
                <button
                    className="k-primary k-button k-grid-edit-command"
                    onClick={(e) => this.buttonClick(e, true)}
                > Edit
                </button>
                <button
                    className="k-button k-grid-remove-command"
                    onClick={
                        (e) => confirm('Confirm deleting: ' + this.props.dataItem.ProductName)
                            && this.buttonClick(e, 'delete')
                    }
                > Remove
                </button>
            </td>
        );
    }
}
import React from 'react';
import { GridColumn, Grid, GridToolbar } from '@progress/kendo-react-grid';
import { process } from '@progress/kendo-data-query';
import { CommandCell } from './my-command-cell.jsx';

export class GridWithState extends React.Component {
    constructor(props) {
        super(props);
        const data = JSON.parse(JSON.stringify(this.props.data));

        const dataState = props.pageable ? { skip: 0, take: this.props.pageSize } : { skip: 0 };
        this.state = {
            dataState: dataState,
            result: process(data, dataState),
            allData: data
        };
    }

    render() {
        return (
            <Grid
                editField="_command"
                expandField="_expanded"
                {...this.props}
                {...this.state.dataState}
                {...this.state.result}

                onItemChange={this.itemChange}
                onExpandChange={this.expandChange}
                onDataStateChange={this.onDataStateChange}
            >
                <GridToolbar>
                    <button
                        title="Add new"
                        className="k-button k-primary"
                        onClick={this.addNew}
                    >Add new
                </button>
                </GridToolbar>

                {this.props.children}

                <GridColumn
                    groupable={false}
                    sortable={false}
                    filterable={false}
                    resizable={false}
                    field="_command"
                    title=" "
                    width="180px"
                    cell={CommandCell}
                />
            </Grid>
        );
    }

    addNew = () => {
        const data = this.state.allData;
        data.unshift({ "_command": true });
        this.setState({
            dataState: { ...this.state.dataState, skip: 0 },
            result: process(data, { ...this.state.dataState, skip: 0 })
        });
    };

    expandChange = (event) => {
        event.dataItem[event.target.props.expandField] = event.value;
        this.forceUpdate();
    };

    itemChange = (event) => {
        const data = this.state.allData;
        if (event.field === "_command" && event.value === 'delete') {
            data.splice(data.findIndex(d => d === event.dataItem), 1);
        } else {
            event.dataItem[event.field] = event.value;
        }
        this.setState({
            result: process(data, this.state.dataState)
        });
    };

    onDataStateChange = (e) => {
        this.setState({
            dataState: e.data,
            result: process(this.state.allData, e.data)
        });
    };
}

Data Operations

The stateful Grid performs its data operations by using the process method of the DataQuery library. To apply the changes and to save the current state of the grid data when a data operation is performed, handle the onDataStateChange event.

onDataStateChange={(e) => {
       this.setState({
           result: process(this.state.unprocessedData ? this.state.unprocessedData : this.props.data, e.data),
           dataState:e.data});
       }}

Editing

To configure the stateful Grid for editing:

  1. Set two different data collections. The first data collection will be displayed in the Grid after the data operations are applied. The second data collection will be used to edit and add items to the collection.

    If the stateful Grid is not intended to be groupable, you can use only one data collection.

    this.state = {
           result: process(this.props.data,{skip:0}),
           dataState: {skip: 0},
           unprocessedData: this.props.data };
  2. Handle the onItemChange event which will fire each time the user updates any of the editors.

    itemChange = (event) => {
           var data = this.state.unprocessedData
           var currentDataState = data;
    
           if (event.field === this.props.editField && event.value === 'delete') {
               data.splice(data.findIndex(d => d === event.dataItem), 1);
           } else {
               event.dataItem[event.field] = event.value;
           }
           this.setState({ result: process(data,this.state.dataState), unprocessedData: data });
       };
  3. Add items to the collection by using a function which you can call from a button click either inside the Grid toolbar or outside the Grid.

    addNew = () => {
           var data = this.state.unprocessedData
           data.unshift({[this.props.editField]: true, Discontinued: false, ProductID: 0})
           this.setState({
               result: process(data, this.props.pageable ? {group:this.state.dataState.group, take: this.state.dataState.take,filter: this.state.dataState.filter , skip: 0, sort:this.state.dataState.sort } : this.state.dataState),
               unprocessedData: data,
               dataState: this.props.pageable ? {group:this.state.dataState.group, take: this.state.dataState.take,filter: this.state.dataState.filter skip: 0, sort:this.state.dataState.sort } : this.state.dataState
           });
       };

In this article