表格状态 (Lit) 指南

表格状态 (Lit) 指南

TanStack Table 具有一个简单的底层内部状态管理系统,用于存储和管理表格的状态。它还允许您选择性地提取您需要在自己的状态管理中管理的任何状态。本指南将引导您了解与表格状态交互和管理表格状态的不同方法。

访问表格状态

您无需进行任何特殊设置即可使表格状态正常工作。如果您未将任何内容传递给 stateinitialState 或任何 on[State]Change 表格选项,表格将自行管理其内部状态。您可以使用 table.getState() 表格实例 API 来访问此内部状态的任何部分。

ts
private tableController = new TableController<Person>(this);

render() {
  const table = this.tableController.table({
    columns,
    data,
    ...
  })

  console.log(table.getState()) //access the entire internal state
  console.log(table.getState().rowSelection) //access just the row selection state
  // ...
}
private tableController = new TableController<Person>(this);

render() {
  const table = this.tableController.table({
    columns,
    data,
    ...
  })

  console.log(table.getState()) //access the entire internal state
  console.log(table.getState().rowSelection) //access just the row selection state
  // ...
}

自定义初始状态

如果对于某些状态,您只需要自定义其初始默认值,您仍然无需自己管理任何状态。您只需在表格实例的 initialState 选项中设置值即可。

ts
render() {
  const table = this.tableController.table({
    columns,
    data,
    initialState: {
      columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order
      columnVisibility: {
        id: false //hide the id column by default
      },
      expanded: true, //expand all rows by default
      sorting: [
        {
          id: 'age',
          desc: true //sort by age in descending order by default
        }
      ]
    },
  })

  return html`...`;
}
render() {
  const table = this.tableController.table({
    columns,
    data,
    initialState: {
      columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order
      columnVisibility: {
        id: false //hide the id column by default
      },
      expanded: true, //expand all rows by default
      sorting: [
        {
          id: 'age',
          desc: true //sort by age in descending order by default
        }
      ]
    },
  })

  return html`...`;
}

注意:对于每个特定的状态,仅在 initialStatestate 中指定,但不要两者都指定。如果您将特定的状态值传递给 initialStatestate,则 state 中的初始化状态将覆盖 initialState 中的任何相应值。

受控状态

如果您需要在应用程序的其他区域轻松访问表格状态,TanStack Table 可以让您轻松地在自己的状态管理系统中控制和管理任何或所有表格状态。您可以通过将自己的状态和状态管理函数传递给 stateon[State]Change 表格选项来实现这一点。

独立受控状态

您可以只控制您需要轻松访问的状态。如果您不需要,则不必控制所有表格状态。建议仅根据具体情况控制所需的状态。

要控制某个特定状态,您需要将相应的 state 值和 on[State]Change 函数都传递给表格实例。

让我们以“手动”服务器端数据获取场景为例,说明过滤、排序和分页。您可以将过滤、排序和分页状态存储在自己的状态管理中,但如果您的 API 不关心这些值(例如列顺序、列可见性等),则可以省略它们。

jsx
import {html} from "lit";

@customElement('my-component')
class MyComponent extends LitElement {
  @state()
  private _sorting: SortingState = []

  render() {
    const table = this.tableController.table({
      columns,
      data,
      state: {
        sorting: this._sorting,
      },
      onSortingChange: updaterOrValue => {
        if (typeof updaterOrValue === 'function') {
          this._sorting = updaterOrValue(this._sorting)
        } else {
          this._sorting = updaterOrValue
        }
      },
      getSortedRowModel: getSortedRowModel(),
      getCoreRowModel: getCoreRowModel(),
    })

    return html`...`
  }
}
//...
import {html} from "lit";

@customElement('my-component')
class MyComponent extends LitElement {
  @state()
  private _sorting: SortingState = []

  render() {
    const table = this.tableController.table({
      columns,
      data,
      state: {
        sorting: this._sorting,
      },
      onSortingChange: updaterOrValue => {
        if (typeof updaterOrValue === 'function') {
          this._sorting = updaterOrValue(this._sorting)
        } else {
          this._sorting = updaterOrValue
        }
      },
      getSortedRowModel: getSortedRowModel(),
      getCoreRowModel: getCoreRowModel(),
    })

    return html`...`
  }
}
//...

完全受控状态

或者,您可以使用 onStateChange 表格选项来控制整个表格状态。它会将整个表格状态提升到您自己的状态管理系统中。请谨慎使用此方法,因为您可能会发现将一些频繁变化的 state 值提升到组件树(例如 columnSizingInfo state)可能会导致性能问题。

为了使此工作正常,可能需要一些额外的技巧。如果您使用 onStateChange 表格选项,则 state 的初始值必须包含您想要使用的所有功能的与所有功能相关的 state 值。您可以手动输入所有初始 state 值,或者以特殊方式使用 table.setOptions API,如下所示。

ts

private tableController = new TableController<Person>(this);

@state()
private _tableState;

render() {
  const table = this.tableController.table({
    columns,
    data,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel()
  })
  const state = { ...table.initialState, ...this._tableState };
  table.setOptions(prev => ({
    ...prev,
    state,
    onStateChange: updater => {
      this._tableState =
        updater instanceof Function ? updater(state) : updater //any state changes will be pushed up to our own state management
    },
  }))

  return html`...`;
}

private tableController = new TableController<Person>(this);

@state()
private _tableState;

render() {
  const table = this.tableController.table({
    columns,
    data,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel()
  })
  const state = { ...table.initialState, ...this._tableState };
  table.setOptions(prev => ({
    ...prev,
    state,
    onStateChange: updater => {
      this._tableState =
        updater instanceof Function ? updater(state) : updater //any state changes will be pushed up to our own state management
    },
  }))

  return html`...`;
}

状态变更回调

到目前为止,我们已经看到了 on[State]ChangeonStateChange 表格选项如何将表格状态更改“提升”到我们自己的状态管理中。但是,在使用这些选项时,有几点需要注意。

1. 状态变更回调必须在其 state 选项中包含相应的状态值

指定 on[State]Change 回调函数会告诉表格实例这是一个受控状态。如果您未指定相应的 state 值,该状态将被“冻结”在其初始值。

jsx
@state()
private _sorting = [];
//...
render() {
  const table = this.tableController.table({
    columns,
    data,
    state: {
      sorting: this._sorting,
    },
    onSortingChange: updaterOrValue => {
      if (typeof updaterOrValue === 'function') {
        this._sorting = updaterOrValue(this._sorting)
      } else {
        this._sorting = updaterOrValue
      }
    },
    getSortedRowModel: getSortedRowModel(),
    getCoreRowModel: getCoreRowModel(),
  })

  return html`...`;
}
@state()
private _sorting = [];
//...
render() {
  const table = this.tableController.table({
    columns,
    data,
    state: {
      sorting: this._sorting,
    },
    onSortingChange: updaterOrValue => {
      if (typeof updaterOrValue === 'function') {
        this._sorting = updaterOrValue(this._sorting)
      } else {
        this._sorting = updaterOrValue
      }
    },
    getSortedRowModel: getSortedRowModel(),
    getCoreRowModel: getCoreRowModel(),
  })

  return html`...`;
}

2. 更新器可以是原始值,也可以是回调函数

on[State]ChangeonStateChange 回调函数的用法与 React 中的 setState 函数完全相同。更新器值可以是新的 state 值,也可以是一个回调函数,该函数接收前一个 state 值并返回新的 state 值。

这有什么影响?这意味着,如果您想在任何 on[State]Change 回调中添加一些额外的逻辑,您可以做到,但您需要检查传入的更新器值是函数还是值。

这就是为什么您会在上面的示例中看到 updater instanceof Function ? updater(state.value) : updater 模式。该模式会检查更新器是否为函数,如果是,则使用前一个 state 值调用该函数以获取新的 state 值。

状态类型

TanStack Table 中的所有复杂状态都有自己的 TypeScript 类型,您可以导入并使用它们。这对于确保您正在为要控制的状态值使用正确的数据结构和属性非常有用。

tsx
import { TableController, type SortingState } from '@tanstack/lit-table'
//...
@state()
private _sorting: SortingState = [
  {
    id: 'age', //you should get autocomplete for the `id` and `desc` properties
    desc: true,
  }
]
import { TableController, type SortingState } from '@tanstack/lit-table'
//...
@state()
private _sorting: SortingState = [
  {
    id: 'age', //you should get autocomplete for the `id` and `desc` properties
    desc: true,
  }
]
我们的合作伙伴
Code Rabbit
AG Grid
订阅 Bytes

您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。

Bytes

无垃圾邮件。您可以随时取消订阅。

订阅 Bytes

您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。

Bytes

无垃圾邮件。您可以随时取消订阅。