当前位置: 首页 > news >正文

React + TypeScript 实战指南:用类型守护你的组件

TypeScript 为 React 开发带来了强大的类型安全保障,这里解析常见的一些TS写法:

一、组件基础类型

1. 函数组件定义

// 显式声明 Props 类型并标注返回值
interface WelcomeProps {
  name: string;
  age?: number; // 可选属性
}

const Welcome: React.FC<WelcomeProps> = ({ name, age = 18 }) => (
  <div>
    Hello {name}, 年龄 {age}
  </div>
);

// React 18+ 需要显式声明 children(如果用到)
interface CardProps {
  children: React.ReactNode; 
}

const Card: React.FC<CardProps> = ({ children }) => (
  <div className="card">{children}</div>
)

2. 类组件写法

type CounterState = { count: number };

class Counter extends React.Component<{}, CounterState> {
  state: CounterState = { count: 0 };

  handleClick = () => {
    this.setState(prev => ({ count: prev.count + 1 }));
  };

  render() {
    return <button onClick={this.handleClick}>点击次数:{this.state.count}</button>;
  }
}

二、Props 高级用法

1. 联合类型与类型守卫

type User = { 
  id: number;
  type: 'admin' | 'user';
  email?: string;
  accessLevel?: number;
};

const UserProfile = ({ user }: { user: User }) => {
  if (user.type === 'admin') {
    return <div>管理员权限:{user.accessLevel}</div>;
  }
  return <div>用户邮箱:{user.email}</div>;
};

2. 默认值与类型推断

interface ButtonProps {
  type?: 'primary' | 'dashed'; // 可选类型自动包含 undefined
  size?: 'large' | 'medium';
}

const MyButton = ({   type = 'primary',   size = 'medium' }: ButtonProps) => (
  <button className={`${type} ${size}`}>按钮</button>
);

三、Hooks 类型实战

1. useState 精确控制

const [user, setUser] = useState<User | null>(null); // 联合类型处理异步数据

// 明确数组项类型
const [todos, setTodos] = useState<{ id: string; text: string }[]>([]);

2. useRef 双重用法

// 操作 DOM
const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
  if (inputRef.current) {
    inputRef.current.focus(); // 需要非空校验
  }
});

// 保存可变值
const timerRef = useRef<number>();
timerRef.current = setInterval(() => {});

3. useContext 类型安全

type Theme = 'light' | 'dark';
const ThemeContext = createContext<Theme>('light');

const App = () => (
  <ThemeContext.Provider value="dark">
    <Child />
  </ThemeContext.Provider>
);

const Child = () => {
  const theme = useContext(ThemeContext); // 自动推断为 Theme 类型
  return <div className={theme}>当前主题</div>;
}

四、事件处理与泛型组件

1. 表单事件精准捕获

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  console.log(e.target.value);
};

<input onChange={handleChange} />

// 鼠标事件
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
  e.preventDefault();
  const rect = e.currentTarget.getBoundingClientRect(); // 正确访问 DOM 属性
};

2. 让组件更灵活:泛型组件

interface ListProps<T> {
  data: T[];
  renderItem: (item: T) => React.ReactNode;
}

function GenericList<T>({ data, renderItem }: ListProps<T>) {
  return (
    <ul>
      {data.map((item, i) => (        <li key={i}>{renderItem(item)}</li>
      ))}    </ul>
  );
}

// 使用
<GenericList<string> 
  data={['a', 'b', 'c']} 
  renderItem={(str) => <div>{str.toUpperCase()}</div>} 
/>

五、常见类型问题速查

// 1. 类型断言:谨慎使用
const element = document.getElementById('root') as HTMLElement;

// 2. 处理可能未初始化的 ref
const videoRef = useRef<HTMLVideoElement>(null!); // 初始化后使用可使用非空断言

// 3. 处理第三方库类型
import { RouteComponentProps } from 'react-router-dom';

interface MatchParams { id: string; }
type Props = RouteComponentProps<MatchParams>;

const ProductPage: React.FC<Props> = ({ match }) => (
  <div>商品ID{match.params.id}</div>
);

相关文章:

  • MVTec HDevelopEVO 24.11体验
  • MsBox.Avalonia 全局修改弹框样式
  • Gradle 配置 Lombok 项目并发布到私有 Maven 仓库的完整指南
  • ​DeepSeek:如何通过自然语言生成HTML文件与原型图?
  • Calico-基本安装、IPIP同节点通信和Proxy_ARP实践 Day01
  • CentOS 7 aarch64上制作kernel rpm二进制包 —— 筑梦之路
  • leetcode day25 28 KMP算法
  • 【ESP-ADF】在 VSCode 安装 ESP-ADF 注意事项
  • 统计建模小贴士
  • Maven 中 SNAPSHOT 版本与 RELEASE 版本的区别
  • C#+Halcon 垂直拼接/裁切避免频繁开辟内存
  • 如何通过卷积神经网络(CNN)有效地提取图像的局部特征,并在CIFAR-10数据集上实现高精度的分类?
  • 基于PyTorch的深度学习3——Tensor与Autograd
  • DApp开发从入门到精通:以太坊/Solana公链生态实战解析
  • 学习工具的一天之(burp)
  • 第5章 使用OSSEC进行监控(网络安全防御实战--蓝军武器库)
  • 数据库设计方面如何进行PostgreSQL 17的性能调优?
  • 优化cache利用、减少cache miss的方法
  • Dify 1.0.0 使用体验
  • 设备管理系统功能与.NET+VUE(IVIEW)技术实现
  • 财政部党组召开2025年巡视工作会议暨第一轮巡视动员部署会
  • 商务部就开展加强战略矿产出口全链条管控工作应询答记者问
  • 海运港口股掀涨停潮!回应关税下调利好,有货代称美线舱位爆了
  • 上海北外滩开发建设五周年交出亮眼答卷,未来五年有何新目标?
  • 王毅人民日报撰文:共商发展振兴,共建中拉命运共同体
  • 《致1999年的自己》:千禧之年的你在哪里?