我有两个组件:App
和 Child
。我使用 useRef
钩子获取 Child
组件中的 DOM 元素并使用它做一些工作。
我还使用 ref
API 将 App
从 Child
组件传递到 React.forwardRef
组件。
App.tsx
:
import { useRef } from "react";
import Child from "./Child";
export default function App() {
const ref = useRef(null);
console.log("App ref: ", ref);
return (
<div className="App">
<Child ref={ref} />
</div>
);
}
Child.ts
:
import React, { useEffect, useRef } from "react";
export default React.forwardRef((props, ref) => {
const innerRef = useRef<HTMLDivElement>(null);
const divElement = ref || innerRef; // TSC throw error here.
useEffect(() => {
if (divElement.current) {
console.log("clientWidth: ", divElement.current.clientWidth);
// do something with divElement.current
}
}, []);
return <div ref={divElement}></div>;
});
我不确定像上面一样使用 innerRef
和转发 ref
是否正确。至少,TSC 会抛出一个错误,这意味着它不允许像这样使用它。
输入'((实例:未知) => void) | MutableRefObject' 不可分配给类型 'string | ((例如:HTMLDivElement | null) => void) |引用对象 |空|不明确的'。
类型 'MutableRefObject' 不可分配给类型 'string | ((例如:HTMLDivElement | null) => void) |引用对象 |空|不明确的'。
类型“MutableRefObject”不可分配给类型“RefObject”。
“当前”属性的类型不兼容。
类型 'unknown' 不能分配给类型 'HTMLDivElement |无效的'。
类型 'unknown' 不能分配给类型 'HTMLDivElement'.ts(2322)
index.d.ts(143, 9): 预期的类型来自属性 'ref',这里在类型 'DetailedHTMLProps
我想在 App
组件中获得正确的引用,并在子组件中使用这个 ref
。我该怎么做?
答案 0 :(得分:1)
您可以在很大程度上忽略 TS 错误,因为您没有为 forwardRef 参数提供类型,因此它不知道 ref/innerRef 是等效类型的。
const divElement = ref || innerRef;
<div ref={divElement}></div>
我有点不明白 - 你是否希望它直接引用 div 元素,而不管是否给定了 ref ?
无论如何,我认为如果你想让它像这样工作,最好使用 useImperativeHandle
钩子,如 useImperativeHandle(ref, () => innerRef.current);
因此,子组件本身使用 innerRef
管理引用,但如果有人确实将引用传递给子组件,它将产生该引用。
export default React.forwardRef((props, ref) => {
const innerRef = useRef<HTMLDivElement>(null);
useImperativeHandle(ref, () => innerRef.current);
useEffect(() => {
if (innerRef.current) {
console.log("clientWidth: ", innerRef.current.clientWidth);
}
}, []);
return <div ref={innerRef}></div>;
});