useState hooks, odata grid state

2 posts, 0 answers
  1. Nick
    Nick avatar
    19 posts
    Member since:
    Oct 2019

    Posted 10 Oct 2020 Link to this post

    Hi All

    Very new to react, trying hooks to simplify code and readability. 

    I am trying to implement the odata service example from: https://www.telerik.com/kendo-react-ui/components/grid/data-operations/odata-server-operations/

    The odata service is fine, I am just trying to get the function setGridState1 to set the grid state to gridState and then call the function toODataString passing in the grid state (and therefore parsing it to an odata string) and then passing it to my rest api.

    I can get the debugger points to trigger, but after I update a filter in the grid and it calls fetchData, gridState is still null?

    Missing something crucial here, not sure what it is though, any help would be great.

     

    import * as React from "react";
    import { Grid, GridColumn as Column } from "@progress/kendo-react-grid";
    import { toODataString } from '@progress/kendo-data-query';
    import { dataService } from "../Services/dataService";
     
    export const AddExistingGrid: React.FC = () => {
      const [selectedID, setSelectedID] = React.useState(null)
      const [editId, setEditId] = React.useState(undefined);
      const [data, setData] = React.useState<any[]>([]);
      const [gridState, setGridState] = React.useState<any>([]);
     
      const fetchData = React.useCallback(async () => {
        debugger;
        const newData = await dataService.getLoanInvOdata(toODataString(gridState));
      }, [setData]);
     
      const setGridState1 = (e) => {
        setGridState(e);
        fetchData();
        debugger;
      }
     
      React.useEffect(() => { fetchData() }, [fetchData]);
     
      return (
        <>
          <div>
            <Grid
              filterable={true}
              sortable={true}
              pageable={true}
              data={data.map(item => ({
                ...item,
                inEdit: item.ProductID === editId,
                selected: item.ProductID === selectedID
              }))}
              onDataStateChange={setGridState1}
            >
              <Column field="id" title="Id" />
              <Column field="ProductName" title="Name" />
              <Column
                field="UnitPrice"
                filter="numeric"
                format="{0:c}"
                title="Price"
              />
              <Column field="UnitsInStock" filter="numeric" title="In stock" />
            </Grid>
     
          </div>
        </>
      );
    };
  2. Stefan
    Admin
    Stefan avatar
    3034 posts

    Posted 12 Oct 2020 Link to this post

    Hello, Nick,

    Thank you for the code.

    I noticed a couple of thinks

    1) We are not passing the gridState value back to the Grid and the Grid is not aware of its current data state. Please check this article for more details:

    https://www.telerik.com/kendo-react-ui/components/grid/data-operations/local-operations/

    2) I assume when we call fetchData inside setGridState1, we are calling it before the state update is finished and we are using the old value of gridState. I can suggest passing the new data state as a parameter for the fetch and using it:

      const setGridState1 = (e) => {
        setGridState(e);
        fetchData(e.data);
        debugger;
      }
    
      const fetchData = React.useCallback(async (newGridState) => {
        debugger;
        const newData = await dataService.getLoanInvOdata(toODataString(newGridState));
      }, [setData]);

    I also updated the demo to use functional components with hooks:

    https://stackblitz.com/edit/react-89hzec?file=app%2Fproducts-loader.jsx

    I hope this is helpful.

    Regards,
    Stefan
    Progress Telerik

    Five days of Blazor, Angular, React, and Xamarin experts live-coding on twitch.tv/CodeItLive, special prizes, and more, for FREE?! Register now for DevReach 2.0(20).

Back to Top