使用 React 在父组件中公开子组件的状态和方法

Expose state and method of child Component in parent with React

我知道这样做不是一个好的模式,但你会明白我为什么要那样做。

我有一个HTable,它使用了第三方库(react-table)

const HTable = <T extends object>({ columns, data, tableInstance}: Props<T>) {
   const instance: TableInstance<T> = useTable<T> (
   // Parameters
   )
   React.useImperativeHandle(tableInstance, () => instance);
}

现在,我想控制父级的列可见性。我做到了:

const Parent = () => {
      const [tableInstance, setTableInstance] = React.useState<TableInstance<SaleItem>>();

      <Table data={data} columns={columns} tableInstance={(instance) => setTableInstance(instance)}

       return tableInstance.columns.map((column) => {
           <Toggle active={column.isVisible} onClick={() =>column.toggleHiden()}
       }
}

列隐藏的很好,但是状态没有更新,切换也没有,我不明白为什么。你能帮我理解一下吗?

编辑:

正在添加沙箱。

https://codesandbox.io/s/react-table-imperative-ref-forked-dilx3?file=/src/App.js

请注意,我不能使用 React.forwardRef,因为我使用 typescript,如果我使用 forwardRef

,React.forwardRef 不允许这样的泛型类型
interface TableProps<T extends object> {
    data: T[],
    columns: Column<T>[],
    tableInstance?:  React.RefObject<TableInstance<T>>,
}

你的问题是 react-tables useTable() 挂钩总是 returns 与 instance 包装器相同的 object(引用永远不会改变)。因此,您的 parent 是 re-setting tableInstance 到相同的 object - 这不会触发更新。实际上,大多数包含的值也被记忆了。要使其响应,请抓住 headerGroups 属性.

const {
  headerGroups,
  ...otherProperties,
} = instance;

React.useImperativeHandle(
  tableInstance,
  () => ({ ...properties }), // select properties individually
  [headerGroups, ...properties],
);