TypeScript + React 实战

React 组件本质是"props 进、UI 出"的函数,TS 能把 props、state、事件处理全部标注清楚。Vite 与 Create React App 都内置 react-ts 模板,开箱即用。

创建项目

用 Vite 创建 React + TS 应用:

npm create vite@latest my-react-app -- --template react-ts
cd my-react-app && npm install && npm run dev

入口文件是 .tsx(TS + JSX),类型检查由 tsc 完成,无需额外配置。

为组件标注 Props

interface 描述组件入参,缺省参数用默认值兜底:

interface GreetingProps {
  name: string;
  times?: number; // 可选属性
}
function Greeting({ name, times = 1 }: GreetingProps) {
  return <h1>{"你好 ".repeat(times)}{name}</h1>;
}
export default function App() {
  return <Greeting name="React" times={2} />;
}

useState 的类型推断与泛型

useState 会从初始值推断类型;复杂状态显式传入泛型:

import { useState } from "react";
interface User { id: number; name: string; }
function App() {
  const [count, setCount] = useState(0);               // 推断为 number
  const [user, setUser] = useState<User | null>(null); // 联合类型
  return (
    <div>
      <button onClick={() => setCount((c) => c + 1)}>计数 {count}</button>
      <button onClick={() => setUser({ id: 1, name: "小明" })}>登录</button>
      <p>{user ? `你好,${user.name}` : "未登录"}</p>
    </div>
  );
}

事件处理函数的类型

事件对象用 React 的类型标注,避免 any:

import { useState, type ChangeEvent, type FormEvent } from "react";
function LoginForm() {
  const [value, setValue] = useState("");
  function onChange(e: ChangeEvent<HTMLInputElement>) {
    setValue(e.target.value);
  }
  function onSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    console.log("提交:", value); // 输出:提交:xxx
  }
  return (
    <form onSubmit={onSubmit}>
      <input value={value} onChange={onChange} />
      <button type="submit">提交</button>
    </form>
  );
}

useRef 与 children 的类型

useRef 需显式指定 DOM 元素类型;若需接收子内容,children 的类型是 React.ReactNode:

import { useRef } from "react";
function FocusInput() {
  const inputRef = useRef<HTMLInputElement>(null); // 初始为 null
  return (
    <>
      <input ref={inputRef} />
      <button onClick={() => inputRef.current?.focus()}>聚焦</button>
    </>
  );
}

小结

React + TS 组合拳:interface 定义 props、useState<T> 约束状态、事件用 ChangeEvent/FormEvent 标注、useRef 指明 DOM 引用。类型让组件的输入输出成为契约,多人协作与重构都更有底气。

笔记加载中…