Get Started

Start a Free Trial (If You Haven’t Already)

KendoReact is a commercial UI library, which means that a KendoReact license has to be purchased in order to develop applications with KendoReact. Since we believe in trying before you buy to ensure that KendoReact is a good fit, we offer a free 30-day trial that is fully functional and also grants access to our legendary technical support during the trial duration.

Set Up the React Project

The easiest way to start with React is to use create-react-app. To scaffold your project structure, follow the installation instructions.

npx create-react-app my-app
cd my-app
npm start

Before we start playing with KendoReact, let's clean up the sample app a bit. Here is a list of suggested edits, with the resulting src/App.js code below:

  • src/App.js
    • Remove everything inside the App container div: <div className="App"> ... </div>
    • Remove the logo.svg import
    • Import {Component} in addition to React
  • Remove the contents of src/App.css
  • Delete src/logo.svg
import React, {Component} from 'react';
import './App.css';

class App extends Component {

  render() {
    return (
      <div className="App">
        <h1>Hello KendoReact!</h1>
      </div>
    );
  }
}

export default App;

Add JSON Data

Let's create some dummy data for our components.

Create a src/categories.json file and copy-paste this content from GitHub inside.

Create a src/products.json file and copy-paste this content from GitHub inside.

Finally, import them in src/App.js:

import categories from './categories.json';
import products from './products.json';

Import KendoReact Components

KendoReact is distributed as multiple NPM packages, scoped to @progress. For example, the name of the Grid package is @progress/kendo-react-grid.

For our example, we will use a Grid, a DropDownList and a Window.

  1. First, let's add the required packages and their dependencies:

    For the Grid:

    npm install --save @progress/kendo-react-grid @progress/kendo-data-query @progress/kendo-react-inputs @progress/kendo-react-intl @progress/kendo-react-dropdowns @progress/kendo-react-dateinputs @progress/kendo-drawing

    For the Window:

    npm install --save @progress/kendo-react-dialogs

    The DropDownList package was installed as a Grid dependency. We also installed another important package: kendo-data-query. It contains useful functions for client-side data operations.

  2. Next, import the installed components into the source code. Add the following to src/App.js:

    import { process } from '@progress/kendo-data-query';
    import { Grid, GridColumn } from '@progress/kendo-react-grid';
    import { DropDownList } from '@progress/kendo-react-dropdowns';
    import { Window } from '@progress/kendo-react-dialogs';

Import the KendoReact CSS Styles

The KendoReact themes are distributed as separate NPM packages. The available theme packages are @progress/kendo-theme-default, @progress/kendo-theme-bootstrap and @progress/kendo-theme-material.

We'll take the Default theme and install it just like we did with the component packages:

npm install --save @progress/kendo-theme-default

Then import the CSS file from the package in src/App.js.

import '@progress/kendo-theme-default/dist/all.css';

If needed, any additional custom styles can go in the empty src/App.css.

Add a KendoReact DropDownList

Let's bind a KendoReact DropDownList to the list of categories.

<p>
  <DropDownList
    data={categories}
    dataItemKey="CategoryID"
    textField="CategoryName"
    />
</p>

The data property of the DropDownList points to an array of objects, and not primitive values. That's why we specified a dataItemKey and a textField.

We can also use the defaultItem property to display a hint for the users when no item is selected. The default item should have a field that matches the textField name.

Finally, we will render the ID of the selected category next to the DropDownList. To do this, define a dropdownlistCategory field in the application state and implement an onChange handler to set it.

Here is the updated src/App.js code:

import React, {Component} from 'react';
import '@progress/kendo-theme-default/dist/all.css';
import './App.css';
import categories from './categories.json';
import products from './products.json';
import { process } from '@progress/kendo-data-query';
import { Grid, GridColumn } from '@progress/kendo-react-grid';
import { DropDownList } from '@progress/kendo-react-dropdowns';
import { Window } from '@progress/kendo-react-dialogs';

class App extends Component {

  state = {
    dropdownlistCategory: null
  }

  handleDropDownChange = (e) => {
    this.setState({
      dropdownlistCategory: e.target.value.CategoryID
    });
  }

  render() {
    return (
      <div className="App">
        <h1>Hello KendoReact!</h1>
        <p>
          <DropDownList
            data={categories}
            dataItemKey="CategoryID"
            textField="CategoryName"
            defaultItem={{CategoryID: null, CategoryName: "Product categories"}}
            onChange={this.handleDropDownChange}
            />
          &nbsp; Selected category ID: <strong>{this.state.dropdownlistCategory}</strong>
        </p>
      </div>
    );
  }
}

export default App;

Add a KendoReact Grid

Now let's bind a KendoReact Grid to the list of products.

<Grid
  data={products}>
  <GridColumn field="ProductName" />
  <GridColumn field="UnitPrice" />
  <GridColumn field="UnitsInStock" />
  <GridColumn field="Discontinued" />
</Grid>

To make things more real-world, let's enable data operations and make some minor improvements to the Grid appearance. Here is what we will do, with the resulting code below:

  • Add a height style to the Grid to activate scrolling.
  • Add user-friendly column titles.
  • Format the numbers in the Price column.
  • Enable paging and sorting. This will require a few additions to the application code, explained below.
  • Display the boolean values in the Discontinued column as checkboxes. For this purpose, we will customize the table cell rendering via the cell property and a custom component.

The Grid is databound to client-side data, so we will enable local data operations. This is how we do it:

  • Enable each data operation separately in the Grid declaration (pageable={true} and sortable={true}).
  • Configure data operation settings and the initial state of the Grid data. For example:
  • The initial page (skip) will be the first one.
  • The page size (take) will be 10.
  • The Grid will be initially sorted by Product Name.
  • We will save all these settings in the App state as this.state.gridDataState and apply them to the Grid in bulk with {...this.state.gridDataState}.
  • Define an onDataStateChange handler. Its purpose is to update this.state.gridDataState after each user interaction. In turn, this will cause the Grid to refresh and display the expected data.
  • To display the correct Grid data, we will bind the Grid to the output of a function, rather than the products array directly. We will use the imported process function, which is part of the kendo-data-query package.
  • As a last step in this section, we will add Grid filtering via the DropDownList. To do that, we will use the existing handleDropDownChange function and add a filter descriptor to gridDataState. We also need to reset the page index (skip) to zero, as the number of data items and pages will decrease.

Here is how App.js should look like at this point:

import React, {Component} from 'react';
import '@progress/kendo-theme-default/dist/all.css';
import './App.css';
import categories from './categories.json';
import products from './products.json';
import { process } from '@progress/kendo-data-query';
import { Grid, GridColumn } from '@progress/kendo-react-grid';
import { DropDownList } from '@progress/kendo-react-dropdowns';
import { Window } from '@progress/kendo-react-dialogs';

class App extends Component {

  state = {
    dropdownlistCategory: null,
    gridDataState: {
      sort: [
        { field: "ProductName", dir: "asc" }
      ],
      page: { skip: 0, take: 10 }
    }
  }

  handleDropDownChange = (e) => {
    let newDataState = { ...this.state.gridDataState }
    if (e.target.value.CategoryID !== null) {
      newDataState.filter = {
        logic: 'and',
        filters: [{ field: 'CategoryID', operator: 'eq', value: e.target.value.CategoryID }]
      }
      newDataState.skip = 0
    } else {
      newDataState.filter = []
      newDataState.skip = 0
    }
    this.setState({
      dropdownlistCategory: e.target.value.CategoryID,
      gridDataState: newDataState
    });
  }

  render() {
    return (
      <div className="App">
        <h1>Hello KendoReact!</h1>
        <p>
          <DropDownList
            data={categories}
            dataItemKey="CategoryID"
            textField="CategoryName"
            defaultItem={{CategoryID: null, CategoryName: "Product categories"}}
            onChange={this.handleDropDownChange}
            />
          &nbsp; Selected category ID: <strong>{this.state.dropdownlistCategory}</strong>
        </p>

        <Grid
          data={process(products, this.state.gridDataState)}
          pageable={true}
          sortable={true}
          {...this.state.gridDataState}
          onDataStateChange={this.handleGridDataStateChange}
          style={{ height: "400px" }}>
          <GridColumn field="ProductName" title="Product Name" />
          <GridColumn field="UnitPrice" title="Price" format="{0:c}" />
          <GridColumn field="UnitsInStock" title="Units in Stock" />
          <GridColumn field="Discontinued" cell={checkboxColumn} />
        </Grid>
      </div>
    );
  }
}

class checkboxColumn extends Component {
  render() {
    return (
        <td>
          <input type="checkbox" checked={this.props.dataItem[this.props.field]} disabled="disabled" />
        </td>
    );
  }
}

export default App;

Add a KendoReact Window

The products array contains some fields, which are not displayed in the Grid. Let's add some interactivity to our application and display additional product details when a Grid row is selected. The information will be displayed in a KendoReact Window.

Here are the required steps.

Define windowVisible and gridClickedRow fields in the application state.

state = {
  // ...
  windowVisible: false,
  gridClickedRow: {}
}

Add a row click handler to the Grid.

<Grid onRowClick={this.handleGridRowClick}>
</Grid>

The handleGridRowClick function will set the windowVisible flag to true and save the Grid data item in the application state. The data item values will be used to render the Window's content.

handleGridRowClick = (e) => {
  this.setState({
      windowVisible: true,
      gridClickedRow: e.dataItem
  });
}

Here is the Window declaration. Notice how the Window will be rendered only if the windowVisible flag value is true.

{this.state.windowVisible &&
  <Window
    title="Product Details"
    onClose={this.closeWindow}
    height={250}>
    <dl>
      <dt>Product Name</dt>
      <dd>{this.state.gridClickedRow.ProductName}</dd>
      <dt>Product ID</dt>
      <dd>{this.state.gridClickedRow.ProductID}</dd>
      <dt>Quantity per Unit</dt>
      <dd>{this.state.gridClickedRow.QuantityPerUnit}</dd>
    </dl>
  </Window>
}

The Window's close handler will set the windowVisible flag to false.

closeWindow = (e) => {
  this.setState({
      windowVisible: false
  });
}

Complete Source Code

Our KendoReact Getting Started application is complete! You can download and run the complete sample application from the kendo-react-getting-started GitHub repository. Alternatively, run, fork and experiment with the application directly in StackBlitz.

Sales Dashboard Sample App

If you want to see the KendoReact components in action, follow this tutorial demonstrating how to build a sales dashboard app using the KendoReact Data Grid, Charts, Material Theme and more. You will also learn how to wrap them in containers.

Next Steps

We are sure that you are looking for more—browse the components section and discover the amazing features that KendoReact brings to the table.

Happy coding!

Not finding the help you need?