joken-前端工程师

  博客园 :: 首页 :: 新随笔 :: :: :: 管理 ::

在 React 中使用 TypeScript 时,除了 React.FC(FunctionComponent)之外,还有许多常用的类型和接口可以帮助开发者更好地定义组件、事件、状态等。这些类型主要来自 @types/react@types/react-dom 包。以下是 React 中常用的一些 TypeScript 类型,涵盖组件、props、事件、ref 等方面的用法,并附上说明和示例。


1. 组件相关类型

React.FC / FunctionComponent

  • 作用: 定义函数组件(已在前文详细介绍)。
  • 示例:
    const MyComponent: React.FC<{ name: string }> = ({ name }) => <div>{name}</div>;
    

React.ComponentType

  • 作用: 表示一个 React 组件类型,可以是函数组件或类组件。
  • 用法: 常用于需要传递组件作为 prop 的场景。
  • 示例:
    interface Props {
      component: React.ComponentType<{ value: number }>;
    }
    const Wrapper: React.FC<Props> = ({ component: Component }) => <Component value={42} />;
    

React.ReactNode

  • 作用: 表示 React 组件的渲染结果,可以是元素、字符串、数字、null、布尔值等。
  • 用法: 用于定义组件的返回值或 children
  • 示例:
    const RenderContent: React.FC<{ content: React.ReactNode }> = ({ content }) => (
      <div>{content}</div>
    );
    // 使用
    <RenderContent content={<span>Hello</span>} />
    

React.ReactElement

  • 作用: 表示一个 React 元素(由 React.createElement 创建的对象),比 ReactNode 更具体。
  • 用法: 需要明确返回 JSX 元素时。
  • 示例:
    const MyElement = (): React.ReactElement => <div>Hello</div>;
    

2. Props 相关类型

React.PropsWithChildren

  • 作用: 为 props 添加可选的 children 属性,简化类型定义。
  • 用法: 替代手动添加 children?: React.ReactNode
  • 示例:
    interface MyProps {
      name: string;
    }
    const MyComponent: React.FC<React.PropsWithChildren<MyProps>> = ({ name, children }) => (
      <div>
        {name}
        {children}
      </div>
    );
    

React.HTMLAttributes

  • 作用: 定义 HTML 元素的标准属性(如 classNameid 等)。
  • 用法: 扩展原生 HTML 元素的 props
  • 示例:
    const CustomDiv: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ className, children }) => (
      <div className={className}>{children}</div>
    );
    

React.ComponentProps

  • 作用: 提取某个组件的 props 类型。
  • 用法: 用于复用现有组件的 props 类型。
  • 示例:
    const Button = ({ label }: { label: string }) => <button>{label}</button>;
    type ButtonProps = React.ComponentProps<typeof Button>;
    const EnhancedButton: React.FC<ButtonProps> = ({ label }) => <Button label={label} />;
    

3. 事件相关类型

React.MouseEvent

  • 作用: 定义鼠标事件(如 onClickonMouseOver)的类型。
  • 用法: 指定事件处理函数的参数类型。
  • 示例:
    const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
      console.log(event.currentTarget.textContent);
    };
    const Button: React.FC = () => <button onClick={handleClick}>Click me</button>;
    

React.ChangeEvent

  • 作用: 定义表单元素的 onChange 事件类型。
  • 用法: 用于输入框、下拉菜单等。
  • 示例:
    const Input: React.FC = () => {
      const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        console.log(e.target.value);
      };
      return <input onChange={handleChange} />;
    };
    

React.FormEvent

  • 作用: 定义表单提交事件类型。
  • 用法: 用于 <form>onSubmit
  • 示例:
    const Form: React.FC = () => {
      const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        console.log("Submitted");
      };
      return <form onSubmit={handleSubmit}><button>Submit</button></form>;
    };
    

4. Ref 相关类型

React.RefObject

  • 作用: 定义 useRef 创建的 ref 对象的类型。
  • 用法: 用于引用 DOM 元素或组件实例。
  • 示例:
    const InputRef: React.FC = () => {
      const inputRef = React.useRef<HTMLInputElement>(null);
      React.useEffect(() => {
        inputRef.current?.focus();
      }, []);
      return <input ref={inputRef} />;
    };
    

React.MutableRefObject

  • 作用: 与 RefObject 类似,但允许修改 current 的值。
  • 用法: 用于自定义 ref 值。
  • 示例:
    const Counter: React.FC = () => {
      const countRef = React.useRef<number>(0);
      const increment = () => {
        countRef.current += 1;
        console.log(countRef.current);
      };
      return <button onClick={increment}>Increment</button>;
    };
    

5. 其他实用类型

React.CSSProperties

  • 作用: 定义内联 CSS 样式的类型。
  • 用法: 用于 style 属性。
  • 示例:
    const Box: React.FC = () => {
      const style: React.CSSProperties = { backgroundColor: "blue", padding: "10px" };
      return <div style={style}>Box</div>;
    };
    

React.JSX.IntrinsicElements

  • 作用: 定义所有 HTML 元素的类型(如 divspan 等)。
  • 用法: 扩展原生 HTML 元素的属性。
  • 示例:
    interface CustomDivProps extends React.JSX.IntrinsicElements["div"] {
      customProp?: string;
    }
    const CustomDiv: React.FC<CustomDivProps> = ({ customProp, ...props }) => (
      <div {...props}>{customProp}</div>
    );
    

React.Dispatch

  • 作用: 定义 useStateuseReducersetState 函数类型。
  • 用法: 指定状态更新函数的类型。
  • 示例:
    const Counter: React.FC = () => {
      const [count, setCount] = React.useState(0);
      const increment: React.Dispatch<React.SetStateAction<number>> = () => setCount((prev) => prev + 1);
      return <button onClick={increment}>{count}</button>;
    };
    

React.SetStateAction

  • 作用: 定义 setState 的参数类型(可以是值或函数)。
  • 示例:
    const [value, setValue] = React.useState<string>("");
    const updateValue = (newValue: React.SetStateAction<string>) => setValue(newValue);
    

常用场景类型总结

类型 作用 示例场景
React.FC 定义函数组件 简单组件
React.ComponentType 表示组件类型 高阶组件、组件作为 prop
React.ReactNode 组件渲染结果 children 或返回值
React.MouseEvent 鼠标事件 onClick 处理
React.ChangeEvent 输入变化事件 <input>onChange
React.RefObject DOM 或组件引用 useRef 操作 DOM
React.CSSProperties 内联样式 style 属性
React.Dispatch 状态更新函数 useStatesetState

注意事项

  1. 避免过度使用 React.FC
    • 如前所述,现代 React 更推荐直接用函数类型声明组件。
  2. 类型推导
    • TypeScript 的类型推导很强大,很多时候不需要显式声明类型。例如,useState 会自动推导状态类型。
  3. 扩展类型
    • 常用 HTML 元素的类型可以通过 React.HTMLAttributesReact.JSX.IntrinsicElements 扩展。

示例:综合应用

import React from "react";

interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
  label: string;
  onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
}

const CustomButton = ({ label, onClick, ...rest }: ButtonProps) => {
  const buttonRef = React.useRef<HTMLButtonElement>(null);
  const style: React.CSSProperties = { padding: "10px" };

  return (
    <button ref={buttonRef} style={style} onClick={onClick} {...rest}>
      {label}
    </button>
  );
};

const App: React.FC = () => {
  const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
    console.log("Clicked:", e.currentTarget.textContent);
  };
  return <CustomButton label="Click Me" onClick={handleClick} />;
};

export default App;

posted on 2025-02-22 18:41  joken1310  阅读(378)  评论(0)    收藏  举报