使用 React 在父组件中公开子组件的状态和方法
Posted
技术标签:
【中文标题】使用 React 在父组件中公开子组件的状态和方法【英文标题】:Expose state and method of child Component in parent with React 【发布时间】:2022-01-12 01:18:06 【问题描述】:我知道这样做不是一个好的模式,但你会明白我为什么要这样做。
我有一个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>>,
【问题讨论】:
看起来您发布的代码 sn-ps 有点混乱。你能纠正这些吗?另外,当您单击 Toggle 时,您能否确认您的 Parent 中的 tableInstance 已重新设置? - 如果您能提供一个我们可以测试的示例,也会很有帮助! 我添加了一个沙箱。注意第二个复选框没有更新。 【参考方案1】:您的问题是 react-table
s useTable()
钩子总是返回与 instance
包装器相同的对象(引用永远不会改变)。因此,您的父母正在将 tableInstance
重新设置为同一个对象 - 这不会触发更新。实际上,大多数包含的值也被记住了。要获得它的响应式获取 headerGroups
属性。
const
headerGroups,
...otherProperties,
= instance;
React.useImperativeHandle(
tableInstance,
() => ( ...properties ), // select properties individually
[headerGroups, ...properties],
);
【讨论】:
你能提供一个沙箱吗?当我这样做时,我有一个无限的渲染。如果我使用 createRef 而不是 useState,问题仍然存在。 @PaulSerre 您的沙箱有一个内联函数作为道具传递给第 109 行的Table
,它会触发重新渲染。检查here
谢谢你,真的!最后一个问题,可以用 ref 来做吗?它是一个可重用的组件,所以如果它与 ref 一起使用会更不稳定
当然,你可以只传递一个 ref 而不是你的 setter 函数。这些属性将在ref.current.columns...
公开。但是这个 ref 不会是反应性的/它不会重新渲染。您将不得不找到另一种方法来使其具有反应性。除此之外,为了使其更易于理解/可重用,也许您可以找到一种方法将表格移动到它自己的自定义钩子中,或者让它接受子切换按钮!
谢谢!最后一个我不能点它,因为我必须制作一个外部按钮,这意味着我必须能够将它放在桌子外面:/以上是关于使用 React 在父组件中公开子组件的状态和方法的主要内容,如果未能解决你的问题,请参考以下文章