# Working with Data

> Learn how to visualise and manage your data in new ways with Infinite Table

Canonical page: https://infinite-table.com/docs/learn/working-with-data/

When working with data, you will mostly interact with the `<DataSource />` component, which is responsible for handling and managing the data and passing it down to the `<InfiniteTable />` component, which is the rendering engine for the DataGrid.

So we provide those two components (as named exports) inside `@infinite-table/infinite-react` package:

- `<DataSource />` - our data-handling component
- `<InfiniteTable />` - our virtualized component

The `<DataSource/>` component is responsible for the data the management layer.

Probably the most important prop for the `<DataSource />` component is the [`idProperty`](https://infinite-table.com/docs/reference/datasource-props/index.md#idProperty) prop. It specifies the property of the data object that is used as a unique identifier for data rows/items.

```tsx
<DataSource<DATA_TYPE>
  idProperty="id"
  data={[]} // or a Promise or function returning a Promise.
/>
```

The `<DataSource />` is a generic React TypeScript component that can be bound to an array of items of the generic type.

In this documentation, we'll use `DATA_TYPE` when referring to the generic type. Rarely, we'll use `T`.

```tsx
<DataSource<DATA_TYPE>>
  <InfiniteTable<DATA_TYPE> />
</DataSource>
```

Most of our examples in these docs have a `Developer` or `Employee` TypeScript data type used as the generic type for the `<DataSource />` component.

```tsx
import { DataSource } from '@infinite-table/infinite-react';

type Employee = {
  id: string | number;
  name: string;
  salary: number;
  department: string;
  company: string;
};

const employees: Employee[] = [
  { id: 1, name: 'Bob', salary: 10_000, department: 'IT', company: 'Bobsons' },
  {
    id: 2,
    name: 'Alice',
    salary: 20_000,
    department: 'IT',
    company: 'Bobsons',
  },
  { id: 3, name: 'John', salary: 30_000, department: 'IT', company: 'Bobsons' },
];

<DataSource<Employee> primaryKey={'id'} data={employees} />;
```

In the snippet above, we see 3 important details:

1. the component is bound to the `Employee` type
2. we use a `primaryKey` property - here it is `id`, but since the bound type is `Employee`, `primaryKey` is `keyof Employee`
3. we pass the `employees` array as the `data` property.

The [`data`](https://infinite-table.com/docs/reference/datasource-props/index.md#data) prop can be either:

- an array of the bound generic type - here `Employee[]`
- a Promise tha resolves to an array like the above
- a function that returns any of the above

```ts
import '@infinite-table/infinite-react/index.css';
import {
  InfiniteTable,
  DataSource,
  InfiniteTableColumn,
} from '@infinite-table/infinite-react';
import * as React from 'react';

type Employee = {
  id: string | number;
  name: string;
  salary: number;
  department: string;
  company: string;
};

const employees: Employee[] = [
  {
    id: 1,
    name: 'Bob',
    salary: 10_000,
    department: 'IT',
    company: 'Bobsons',
  },
  {
    id: 2,
    name: 'Alice',
    salary: 20_000,
    department: 'IT',
    company: 'Bobsons',
  },
  {
    id: 3,
    name: 'John',
    salary: 30_000,
    department: 'IT',
    company: 'Bobsons',
  },
  {
    id: 4,
    name: 'Jane',
    salary: 35_000,
    department: 'Marketing',
    company: 'Janies',
  },
  {
    id: 5,
    name: 'Mary',
    salary: 40_000,
    department: 'Marketing',
    company: 'Janies',
  },
];

// simulate data-loading with a 1500ms delay
const data = new Promise<Employee[]>((resolve) => {
  setTimeout(() => {
    resolve(employees);
  }, 1500);
});

export default function App() {
  return (
    <DataSource<Employee> data={data} primaryKey="id">
      <InfiniteTable<Employee>
        debugId="basic-example"
        columnDefaultWidth={130}
        columns={columns}
      />
    </DataSource>
  );
}

const columns: Record<string, InfiniteTableColumn<Employee>> = {
  id: {
    field: 'id',
    type: 'number',
    defaultWidth: 80,
  },
  name: {
    field: 'name',
  },
  salary: { field: 'salary', type: 'number' },
  department: { field: 'department', header: 'Dep.' },
  company: { field: 'company' },
};
```

## Data Loading Strategies

We're aware there are countless strategies for loading data - each with its own strengths. We decided we should focus on building what we do best, namely building virtualized components, so we encourage you to use your preferred data-fetching library/solution. This being said, we still provide you with the flexibility you need when using the `<DataSource/>`, so here's what you can use for the [`data`](https://infinite-table.com/docs/reference/datasource-props/index.md#data) prop of the component:

- an array of the bound type
- a Promise that resolves to an array of the bound type
- a function that returns any of the above

While you're loading the data, you can always render a loading indicator - pass the [`loading`](https://infinite-table.com/docs/reference/datasource-props/index.md#loading) prop into the component (along with [`loadingText`](https://infinite-table.com/docs/reference/infinite-table-props.md#loadingText) prop in the `<InfiniteTable />` component if you want to customize the message).

### Using fetch

For basic datasets, which have simple data requirements, using `fetch` is probably sufficient, so here is an example:

**Example: Using fetch for remote data**

```ts files=["using-fetch-example.page.tsx","columns.ts"]

```

#### Re-fetching on change

It's important to note you can re-fetch data by changing the reference you pass as the `data` prop to the `<DataSource/>` component.

Passing another [`data`](https://infinite-table.com/docs/reference/datasource-props/index.md#data) function, will cause the component to re-execute the function and thus load new data.

Alternatively, you can use the [`refetchKey`](https://infinite-table.com/docs/reference/datasource-props/index.md#refetchKey) prop to trigger a re-fetch - give it a new value (eg: use it as a counter, and increment it) and the component will re-fetch the data.

**Example: Re-fetching data**

```ts files=["refetch-example.page.tsx","columns.ts"]

```

## Live Updates

You can update your data in real-time by using our [DataSource API](https://infinite-table.com/docs/reference/datasource-api/index.md).

Read more about how to use our API to update your data in real-time
