reactjs - 如何通过数组将 ref 传递给 typescript 中的 forwardRef 并做出反应?
问题描述
我有一个在 codepen 中创建的示例。该表使用 th 呈现,但在我的 IDE 中,打字稿抱怨此行的类型:
<TH handleSort={handleSort} ref={refsTh[ind]}>
--- 错误类型 'MutableRefObject' 不能分配给类型 '((instance: HTMLTableHeaderCellElement | null) => void) | 参考对象 | 空 | 不明确的'。类型“MutableRefObject”不可分配给类型“RefObject”。属性“当前”的类型不兼容。类型“未知”不可分配给类型“HTMLTableHeaderCellElement | 无效的'。类型“未知”不可分配给类型“HTMLTableHeaderCellElement”。
我在不传递数组而是传递单个 ref 时使这个示例工作。问题似乎是因为我在数组中动态创建 useRefs。有人可以请教吗?谢谢
示例代码: https ://codepen.io/inspiraller/pen/OJMRZWQ
// import React from 'react';
// ######################################
type shapeTH = {
handleSort: () => void,
children: React.ReactNode // BUG: can't pass children any other way to forwardRef
};
type Ref = HTMLTableHeaderCellElement | null;
const TH = React.forwardRef<Ref, shapeTH>(
({children, handleSort}, ref) => (
<th ref={ref} onClick={handleSort}>
<span className="thSpan">{children}</span>
</th>
)
);
// const TH:React.FC<shapeTH> = ({children, handleSort}) => (
// <th onClick={handleSort}>
// <span className="thSpan">{children}</span>
// </th>
// );
// ##################################################
const App:React.FC = () => {
const arrTh=['id', 'name', 'colour'];
type shapeRef = ReturnType<typeof React.useRef>;
const refsTh: Array<shapeRef> = arrTh.map(() => (
React.useRef<HTMLTableHeaderCellElement>(null)
));
const handleSort: shapeTH['handleSort'] = () => {};
return (
<table className="tableGeneric">
<thead>
<tr>
{
arrTh.map((item, ind) => (
<TH handleSort={handleSort} ref={refsTh[ind]}>
{item}
</TH>
))
}
</tr>
</thead>
</table>
);
};
// export default App;
ReactDOM.render(
<App/>,
document.getElementById('app')
);
解决方案
useRef
是一个泛型,你知道是因为你写的React.useRef<HTMLParagraphElement>(null)
正确。变量的类型refOne
将被推断为React.RefObject<HTMLParagraphElement>
。
问题是您手动分配了一个比refOne
这更模糊的类型。当您查看useRef
函数的返回类型时,您不知道将使用什么泛型类型来调用它type shapeRef = ReturnType<typeof React.useRef>
,React.MutableRefObject<unknown>
所以.unknown
ref.current
当变量的类型从其值已知时,您无需手动将类型分配给变量。这可以:
const App: React.FC = () => {
const refOne = React.useRef<HTMLParagraphElement>(null);
const handleSort = () => { };
return (<P handleSort={handleSort} ref={refOne}>hello</P>);
};
对于您的数组示例,您有同样的问题。
const refsTh = arrTh.map(() => (
React.useRef<Ref>(null)
));
仅供参考#1:如果数组可以更改长度,您可能不想在数组上调用钩子,但是您App
有一个固定的数组,所以没关系。
仅供参考#2:您可以使用React.PropsWithChildren<P>
添加children
道具。但是将其设置为常规道具也可以。
推荐阅读
- ajax - 加载失败:对预检请求的响应未通过访问控制检查
- oauth - Oauth 访问令牌:如果令牌有 30 天的有效期,我应该每周刷新一次吗?
- wordpress - 将 Watson Assistant 实例嵌入到 Wordpress
- json - Scala Play - Json 解析
- python - Python,操作数据框
- swift - 如何将谷歌文档中的图像放入 swift 应用程序?
- javascript - 使用 jquery 或纯 JS 处理 JSONP 请求?
- .net - 为什么多个线程在 .NET 中不能更快(它们在 Java 中)
- html - 将鼠标悬停在下拉菜单上时闪烁的菜单
- android - SocketTimeoutException:连接超时 Android ksoap