如何在 React 中使用 refs 和 Typescript

新手上路,请多包涵

我正在使用带有 React 的 Typescript。我无法理解如何使用 refs 来获得关于 refs 引用的 react 节点的静态类型和智能感知。我的代码如下。

 import * as React from 'react';

interface AppState {
    count: number;
}

interface AppProps {
    steps: number;
}

interface AppRefs {
    stepInput: HTMLInputElement;
}

export default class TestApp extends React.Component<AppProps, AppState> {

constructor(props: AppProps) {
    super(props);
    this.state = {
        count: 0
    };
}

incrementCounter() {
    this.setState({count: this.state.count + 1});
}

render() {
    return (
        <div>
            <h1>Hello World</h1>
            <input type="text" ref="stepInput" />
            <button onClick={() => this.incrementCounter()}>Increment</button>
            Count : {this.state.count}
        </div>
    );
}}

原文由 Akshar Patel 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 797
2 个回答

如果您使用的是 React 16.3+,则 建议 的创建 refs 的方法是使用 React.createRef()

 class TestApp extends React.Component<AppProps, AppState> {
    private stepInput: React.RefObject<HTMLInputElement>;
    constructor(props) {
        super(props);
        this.stepInput = React.createRef();
    }
    render() {
        return <input type="text" ref={this.stepInput} />;
    }
}

当组件挂载时, ref 属性的 current 属性将分配给引用的组件/DOM 元素,并在卸载时分配回 null 。因此,例如,您可以使用 this.stepInput.current 访问它。

有关 RefObject 的更多信息,请参阅 @apieceofbart 的回答 或添加 了 PR createRef()


如果您使用的是早期版本的 React (<16.3) 或需要更细粒度地控制何时设置和取消设置 refs,则可以使用 “回调 refs”

 class TestApp extends React.Component<AppProps, AppState> {
    private stepInput: HTMLInputElement;
    constructor(props) {
        super(props);
        this.stepInput = null;
        this.setStepInputRef = element => {
            this.stepInput = element;
        };
    }
    render() {
        return <input type="text" ref={this.setStepInputRef} />
    }
}

当组件挂载时,React 将使用 DOM 元素调用 ref 回调,并在卸载时使用 null 调用它。因此,例如,您可以简单地使用 this.stepInput 访问它。

通过将 ref 回调定义为类上的绑定方法而不是内联函数(如在此答案的 先前版本 中),您可以避免在更新 期间调用两次 回调。


曾经 一个 API,其中 ref 属性是一个字符串(请参阅 Akshar Patel 的回答),但由于 一些 问题,强烈建议不要使用字符串引用,最终会删除。


于 2018 年 5 月 22 日编辑,在 React 16.3 中添加了新的引用方式。感谢@apieceofbart 指出有一种新方法。

原文由 Jeff Bowen 发布,翻译遵循 CC BY-SA 4.0 许可协议

React.createRef (类补偿)

 class ClassApp extends React.Component {
  inputRef = React.createRef<HTMLInputElement>();

  render() {
    return <input type="text" ref={this.inputRef} />
  }
}

React.useRef (挂钩/功能比较)

a) 对 React 管理的 DOM 节点使用只读引用:

 const FunctionApp = () => {
  // note the passed-in `null` arg ----------------v
  const inputRef = React.useRef<HTMLInputElement>(null)
  return <input type="text" ref={inputRef} />
}

inputRef.current 通过使用 null 初始化其值,变为 readonly 属性。

b) 对类似于实例变量的任意存储值使用 可变引用

 const FunctionApp = () => {
  const renderCountRef = useRef(0)
  useEffect(() => {
    renderCountRef.current += 1
  })
  // ... other render code
}

注意:在这种情况下,不要用 null 初始化 useRef - 它会使 renderCountRef 类型 readonly例如 3901d911249f17164)如果您 需要 提供 null 作为初始值,请执行以下操作:

 const renderCountRef = useRef<number | null>(null)

回调参考(两者)

 // Function component example, class analogue
const FunctionApp = () => {
  const handleDomNodeChange = (domNode: HTMLInputElement | null) => {
    // ... do something with changed dom node.
  }
  return <input type="text" ref={handleDomNodeChange} />
}

注意: 字符串引用 被认为是遗留的,在此答案的范围内被省略。

游乐场样本

原文由 ford04 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进