You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flow中为useRef Hook添加类型标注?

How to Type Annotate the useRef Hook for HTML Inputs in Flow

Got it, let's fix your Flow type annotation issue with useRef—this is a common gotcha when switching between Flow and TypeScript. The error you're seeing happens because Flow infers inputRef.current as null by default (since you didn't provide a type or initial value), and null doesn't have a focus() method.

Here's the Correct Flow Syntax for Your Case

In Flow, you need to explicitly specify the ref's type via a generic and initialize it with null (since the ref will be null until the component mounts). Here's how to adjust your code:

// @flow
import * as React from 'react';
import { useRef, useState } from "react";
import type { ComponentType } from "react";

const App: ComponentType<{}> = () => {
  const [email, setEmail] = useState("");
  
  // Add type annotation for the change event to keep Flow happy
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
    e.preventDefault();
    setEmail(e.target.value);
  };
  
  // Annotate useRef with the HTML element type and initialize to null
  const inputRef = useRef<HTMLInputElement>(null);
  
  return (
    <>
      <input ref={inputRef} name="email" value={email} onChange={handleChange} />
      <button onClick={() => {
        // Use optional chaining to safely call focus() (handles the null case)
        inputRef.current?.focus();
        
        // Alternatively, if you're certain the ref is set (like on button click post-mount),
        // you can use a type assertion to tell Flow current isn't null:
        // (inputRef.current: HTMLInputElement).focus();
      }}>Ref</button>
    </>
  );
};

export default App;

Key Differences from TypeScript

  1. Initial Value Requirement: Unlike TypeScript, Flow requires you to pass an initial value to useRef when using a generic type. Since the ref starts as null before the input mounts, we pass null here to match the expected type.
  2. Type Inference: Flow infers the current property type from the combination of the generic and initial value. So useRef<HTMLInputElement>(null) gives us a ref with current: HTMLInputElement | null.

Why Your Original Code Failed

When you wrote const inputRef = useRef(); without any type or initial value, Flow inferred inputRef.current as void (or null in some contexts), which doesn't have the focus() method. By adding the generic type and initial null value, we tell Flow exactly what type of element the ref will hold once the component mounts.

Bonus: Safe Access to the Ref

Using ?. (optional chaining) is the safest way to call methods on the ref, as it gracefully handles edge cases where current might still be null. In your button click scenario, the input will have mounted by the time the button is clicked, so the type assertion is also valid if you prefer that syntax.

内容的提问来源于stack exchange,提问作者Noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:30:20