React Ref TypeScript 用法

在使用React开发前端应用的过程中,我们经常需要操作DOM元素或者其他React组件实例。为了解决这个问题,React提供了一种叫做Ref的特殊对象。而在TypeScript中,我们同样可以很方便地使用Ref来操作DOM元素或其他React组件实例。
本文将详细介绍React Ref在TypeScript中的用法,包括创建Ref、使用Ref以及Ref的不同类型。
创建Ref
在TypeScript中,我们可以使用泛型来指定Ref的类型。以下是创建Ref的两种方式:
使用createRef函数
import React, { useRef } from 'react';
const myRef = useRef<HTMLInputElement>(null);
在上面的代码中,我们使用了useRef函数来创建一个Ref,并且指定了Ref的类型为HTMLInputElement。如果我们要操作的是一个div元素,那么我们可以将类型指定为HTMLDivElement。
使用callback函数
import React, { createRef } from 'react';
class MyComponent extends React.Component {
  private myRef = createRef<HTMLInputElement>();
  render() {
    return <input ref={this.myRef} />;
  }
}
以上代码中,我们使用createRef函数来创建一个Ref,并且指定了Ref的类型为HTMLInputElement。在类组件中,我们可以将Ref直接绑定到DOM元素上。
使用Ref
创建了Ref之后,我们可以通过Ref来操作DOM元素或其他React组件实例。
操作DOM元素
import React, { useRef } from 'react';
const MyComponent = () => {
  const inputRef = useRef<HTMLInputElement>(null);
  const focusInput = () => {
    inputRef.current?.focus();
  };
  return (
    <div>
      <input ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
};
在上述代码中,我们创建了一个input元素的Ref,并且创建了一个按钮,当点击按钮时调用focusInput函数,将input元素获得焦点。通过Ref,我们可以很方便地操作DOM元素的属性和方法。
操作React组件实例
import React, { createRef } from 'react';
class ChildComponent extends React.Component {
  public doSomething() {
    console.log('Child Component did something');
  }
}
class ParentComponent extends React.Component {
  private childRef = createRef<ChildComponent>();
  componentDidMount() {
    this.childRef.current?.doSomething();
  }
  render() {
    return <ChildComponent ref={this.childRef} />;
  }
}
在上面的代码中,我们创建了一个父组件ParentComponent和一个子组件ChildComponent。我们在父组件中创建了一个子组件实例的Ref,并在componentDidMount生命周期方法中调用了子组件实例的doSomething方法。通过Ref,我们可以很方便地获取并调用React组件实例的方法。
Ref的不同类型
在React中,Ref可以分为两种不同类型:Mutable Ref和Callback Ref。在TypeScript中,我们可以通过泛型和回调函数来声明不同类型的Ref。
Mutable Ref
通过useRef函数创建的Ref就是Mutable Ref,它的类型是一个可变的对象。Mutable Ref在整个生命周期中保持不变,其值可以被任意改变。
Callback Ref
通过callback函数创建的Ref就是Callback Ref,它的类型是一个回调函数。Callback Ref在每次渲染时都会被调用,因此它可以获取到最新的DOM元素或React组件实例。
下面是一个使用Callback Ref的示例:
import React, { useRef, forwardRef, useImperativeHandle } from 'react';
interface ChildProps {}
const ChildComponent = forwardRef((props: ChildProps, ref) => {
  const inputRef = useRef<HTMLInputElement | null>(null);
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current?.focus();
    }
  }));
  return <input ref={inputRef} />;
});
interface ParentProps {}
const ParentComponent: React.FC<ParentProps> = () => {
  const childRef = useRef<{ focus: () => void }>(null);
  const focusChildInput = () => {
    childRef.current?.focus();
  };
  return (
    <div>
      <ChildComponent ref={childRef} />
      <button onClick={focusChildInput}>Focus Child Input</button>
    </div>
  );
};
在上面的代码中,我们创建了一个子组件ChildComponent,并使用useImperativeHandle钩子函数来定义一个focus方法,该方法可以让子组件的input元素获取焦点。然后我们在父组件ParentComponent中创建了一个子组件实例的Ref,并通过该Ref来调用子组件的focus方法。
总结
通过本文的介绍,我们可以了解到在React中如何使用Ref来操作DOM元素或其他React组件实例。在TypeScript中,我们可以很方便地使用泛型和回调函数来声明不同类型的Ref,从而更好地控制和管理我们的代码。
极客教程