react在typescript下传递ref给子组件
2023-02-11 19:06:59    70    0    0
admin

在tsx下使用

默认情况下,我们不能在函数组件上使用 ref 属性,因为它们没有实例。

如果要在函数组件中使用 ref,可以使用 forwardRef 包裹组件函数使用(可与 useImperativeHandle 结合使用)。

被 forwardRef 包裹的组件函数除 props,还要多传入第二个参数:ref,即从外部传入的 ref。

useImperativeHandle 接收三个参数,第一个是 forwardRef 传入的 ref;第二个参数是 handle 函数,返回要向外暴露的值,通常是对象;第三个参数是依赖数组,根据依赖变化执行更新,非必需参数。

  1. import { useRef, forwardRef, Ref, useImperativeHandle, ElementRef, useEffect } from "react";
  2. // 组件,有两种定义类型的方式
  3. // 组件1,一种是使用 forwardRef 的泛型
  4. // forwardRef 泛型第一个参数是 Ref 类型,
  5. // 第二个参数是 props 类型,不传时默认类型为{},
  6. // 注意,forwardRef 泛型与内部包裹函数的参数顺序恰恰相反,易造成歧义
  7. const Component1 = forwardRef<HTMLInputElement, {}>((props, ref) => <input ref={ref} />);
  8. // 组件2,另一种是是在函数参数上直接定义类型, **该方式验证有效**
  9. // 注意,在函数参数上定义类型时,ref 参数类型需要使用Ref泛型包裹,而 forwardRef 泛型则不需要
  10. const type useImperativeHandle返回的类型 = React.Ref<{
  11. sayHello: () => void
  12. }>
  13. const Component2 = forwardRef(
  14. // ref 类型使用了 Ref 泛型包裹
  15. (props: {}, ref: useImperativeHandle返回的类型) => {
  16. // ref 为第一个参数,返回带有 sayHello 方法对象的函数为第二个参数
  17. useImperativeHandle(ref, () => {
  18. return {
  19. sayHello: () => console.log("hello"),
  20. };
  21. });
  22. return <div>Say hello in console.log</div>;
  23. }
  24. );
  25. // App
  26. export default function App() {
  27. // 在父组件中使用时需要使用 ElementRef 泛型,并使用 typeof 获取组件的 ref 类型
  28. const textInputRef = useRef<ElementRef<typeof Component1>>(null);
  29. const helloRef: useImperativeHandle返回的类型 = useRef(null); // **该方式验证有效**
  30. useEffect(() => {
  31. // 聚焦textInputRef
  32. if (textInputRef.current) textInputRef.current.focus();
  33. // 调用helloRef的sayHello方法
  34. if (helloRef.current) helloRef.current.sayHello();
  35. }, []);
  36. return (
  37. <>
  38. <Component1 ref={textInputRef} />
  39. <Component2 ref={helloRef} />
  40. </>
  41. );
  42. }

可以看到,有两种方式定义 forwardRef 组件的类型。

一种是在 forwardRef 泛型中定义 ref 类型与 props 类型,需要注意的是泛型中是 ref 类型在前,props 类型在后,而函数组件中是 props 在前,ref 在后。

另一种则是直接在函数组件的参数中定义类型,需要注意的是这种方式定义 ref 类型需要使用 Ref 泛型。

另外在父组件中,使用 useRef 时,则需要通过 ElementRef 泛型与 typeof 结合获取 ref 类型。

Pre: submodule使用笔记

Next: create-react-app开发npm组件

70
Sign in to leave a comment.
No Leanote account? Sign up now.
0 comments
Table of content