首页 > 解决方案 > 如何通过数组将 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')
);


标签: reactjstypescript

解决方案


useRef是一个泛型,你知道是因为你写的React.useRef<HTMLParagraphElement>(null)正确。变量的类型refOne将被推断为React.RefObject<HTMLParagraphElement>

问题是您手动分配了一个比refOne这更模糊的类型。当您查看useRef函数的返回类型时,您不知道将使用什么泛型类型来调用它type shapeRef = ReturnType<typeof React.useRef>React.MutableRefObject<unknown>所以.unknownref.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道具。但是将其设置为常规道具也可以。


推荐阅读