我试图使用父组件中的ref来侦听子组件中的某些ref事件,其中ref使用React.forwardRef连接到子组件。然而,当我引用ref.current时,我在子组件中收到了一个令人毛骨悚然的抱怨,它说:
属性'current‘在类型'Ref’上不存在。属性“current”不存在于类型上(例如: HTMLDivElement) => void‘
如何在React.forwardRef组件中引用ref?谢谢。
index.tsx:
import * as React from "react";
import ReactDOM from "react-dom";
const Component = React.forwardRef<HTMLDivElement>((props, ref) => {
React.useEffect(() => {
const node = ref.current;
const listen = (): void => console.log("foo");
if (node) {
node.addEventListener("mouseover", listen);
}
return () => {
node.removeEventListener("mouseover", listen);
};
}, [ref]);
return <div ref={ref}>Hello World</div>;
});
export default Component;
const App: React.FC = () => {
const sampleRef = React.useRef<HTMLDivElement>(null);
return <Component ref={sampleRef} />;
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);发布于 2020-06-06 22:49:00
Refs不一定是具有current属性的对象。它们也可以是函数。因此,类型错误指出,您可能会被传递给后者之一。您需要编写代码,以便它可以同时处理这两种变体。
这可能有点棘手,但它是可行的。我们的效果不能回到传递给我们的函数上,因为这个函数可以做任何事情,而且编写时没有考虑到我们的useEffect。因此,我们需要创建自己的ref,我称之为myRef。
现在有两个参考文献:一个是传入的,另一个是本地的。要填充这两种元素,我们需要自己使用refs的函数形式,在这个函数中,我们可以将div元素分配给这两个参考文献:
const Component = React.forwardRef<HTMLDivElement>((props, ref) => {
const myRef = useRef<HTMLDivElement | null>(null);
React.useEffect(() => {
const node = myRef.current;
const listen = (): void => console.log("foo");
if (node) {
node.addEventListener("mouseover", listen);
}
return () => {
node.removeEventListener("mouseover", listen);
};
}, [ref]);
return (
<div ref={(node) => {
myRef.current = node;
if (typeof ref === 'function') {
ref(node);
} else if (ref) {
ref.current = node;
}
}}>Hello World</div>
);
});发布于 2022-06-08 18:25:11
详述@Nicholas答复:
import React, { MutableRefObject, Ref, useEffect } from "react";
import { TextInput } from "react-native";
type CustomTextInputProps = {};
export const CustomTextInput = React.forwardRef<
TextInput,
CustomTextInputProps
>((props, ref) => {
const localRef = React.useRef<TextInput | null>(null);
useEffect(() => {
// using the local ref
localRef.current?.focus();
}, []);
return <TextInput {...props} ref={assignRefs(localRef, ref)} />;
});
const assignRefs = <T extends unknown>(...refs: Ref<T | null>[]) => {
return (node: T | null) => {
refs.forEach((r) => {
if (typeof r === "function") {
r(node);
} else if (r) {
(r as MutableRefObject<T | null>).current = node;
}
});
};
};发布于 2022-09-16 17:30:42
我四处搜索,因为这是另一个钩子,如useForwardRef很好的候选。这是提议,https://github.com/facebook/react/issues/24722
我自己也试过,对此效果很好。
const InputField = React.forwardRef<HTMLInputElement, InputFieldProps>(
(props, ref) => {
const inputRef = useForwardRef<HTMLInputElement>(ref);
const onLabelClick = () => {
inputRef.current?.focus();
};
return <input ref={inputRef} />
);当然,这基本上是相同的代码在最初的答案,但写成一个钩子。
const useForwardRef = <T,>(
ref: ForwardedRef<T>,
initialValue: any = null
) => {
const targetRef = useRef<T>(initialValue);
useEffect(() => {
if (!ref) return;
if (typeof ref === 'function') {
ref(targetRef.current);
} else {
ref.current = targetRef.current;
}
}, [ref]);
return targetRef;
};注意:钩子的名字是有争议的,它可以被命名为useCopyRef,useBorrowRef什么的。为了简单起见,因为它是为forwardRef创建的,所以我们将其命名为useForwardRef,但实际上它与转发无关。
https://stackoverflow.com/questions/62238716
复制相似问题