React 开发应该了解的 TypeScript 模式

随着 TypeScript 在 React 生态系统中的采用率不断提高,了解高级模式可以显著提高您的代码质量、可扩展性和开发人员体验。本文重点介绍了 React 开发的基本 TypeScript 模式,以及帮助你充分利用这些工具的实际示例。

Discriminated unions (管理复杂的状态(数据))

Discriminated unions 是处理具有多个变体或 "模式" 的状态的有效方法。通过将联合类型与 "discriminator" 属性组合在一起,您可以确保类型安全并避免由无效状态引起的错误。

示例 状态加载

ts 复制代码
type FetchState =  
| { status: 'idle' }  
| { status: 'loading' }  
| { status: 'success'; data: string[] }  
| { status: 'error'; error: string };


const fetchReducer = (state: FetchState, action: any): FetchState => {  
  switch (action.type) {  
  case 'FETCH_START':  
    return { status: 'loading' };  
  case 'FETCH_SUCCESS':  
    return { status: 'success', data: action.payload };  
  case 'FETCH_ERROR':  
    return { status: 'error', error: action.payload };  
  default:  
    return state;  
  }  
};

为什么有用 Discriminated unions 允许您的状态转换是显式的,从而避免无效的组合,例如同时具有 dataerror

泛型:定义具有复用性和适应性的组件

泛型使你的组件或 hook 可重用,同时保留强类型定义。这对于处理具有不同数据结构的列表、表单或 API 特别有用。

示例, 可复用的表格组件

ts 复制代码
type TableProps<T> = {  
  data: T[];  
  renderRow: (item: T) => React.ReactNode;  
};  
  
function Table<T>({ data, renderRow }: TableProps<T>) {  
  return (  
    <table>  
      <tbody>
       {data.map((item, index) => <tr key={index}>{renderRow(item)}</tr>)}
      </tbody>  
  </table>);  
}

// Usage  
type User = { id: number; name: string };  
const users: User[] = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];  
  
<Table  
  data={users}  
  renderRow={(user) => (<>  
    <td>{user.id}</td>  
    <td>{user.name}</td>  
  </>)}  
/>;

为什么有用

泛型使您的组件具有适应性,而不会失去类型推理的优势,从而使您免于重复的代码。

Mapped Types: props 和 state 之间的转换

映射类型允许您通过转换现有类型来创建新类型。这在定义派生 state 或 prop 接口时特别有用。

示例, 部分表单prpos

ts 复制代码
type FormValues = {  
  name: string;  
  email: string;  
  age: number;  
};

type FormErrors<T> = {  
  [K in keyof T]?: string;  
};

const errors: FormErrors<FormValues> = {  
  name: "Name is required",  
  email: "Email is invalid",  
};

为什么有用

映射类型非常适合管理具有不同属性的表单、API 或配置对象。

React props 和 state 的高级类型

带有 defaultProps 的类型属性

使用 defaultProps 时,您可以通过利用 TypeScript 的部分类型支持来确保类型安全

ini 复制代码
type ButtonProps = {  
  label: string;  
  onClick?: () => void;  
};  
  
const Button = ({ label, onClick = () => {} }: ButtonProps) => (  
  <button onClick={onClick}>{label}</button>  
);

只读 State

要在您的状态中强制执行不可变性,请使用 ReadonlyReadonlyArray

ts 复制代码
type State = Readonly<{  
  items: string[];  
}>;  
  
const [state, setState] = useState<State>({ items: ['Item 1'] });

为什么有用

强类型的 props 和 state 减少了运行时错误,并使其他开发人员清楚地了解了你的意图。

使用 TypeScript 和 React 的动态表单

动态表单通常涉及依赖于用户输入的复杂类型。TypeScript 可以帮助强制执行正确性,即使对于动态结构也是如此。

动态表单字段

ts 复制代码
type Field = {  
  id: string;  
  label: string;  
  value: string;  
};

type FormState = {  
  fields: Field[];  
};

const DynamicForm: React.FC = () => {  
const [formState, setFormState] = useState<FormState>({ fields: [] });  
  
const addField = () => {  
  setFormState((prev) => ({  
    fields: [...prev.fields, { id: Date.now().toString(), label: '', value: '' }],  
  }));  
};  
  
  return (  
    <div>  
      {formState.fields.map((field) => (  
        <input  
            key={field.id}  
            placeholder={field.label}  
            value={field.value}  
            onChange={(e) =>  
            setFormState((prev) => ({  
            fields: prev.fields.map((f) =>  
              f.id === field.id ? { ...f, value: e.target.value } : f  
            ),  
       }))}  
    />  
  ))}  
     <button onClick={addField}>Add Field</button>  
    </div>  
  );  
};

为什么有用

动态表单是许多应用程序中的常见功能。TypeScript 确保每个字段都正确键入和更新。

总结

TypeScript 不仅仅是一个静态类型工具------它还是一种编写更健壮、可维护和可扩展的 React 应用程序的方法。通过掌握 discriminated unions(可区分联合)、泛型和高级 prop 类型等模式,您可以在项目中释放 TypeScript 的全部潜力。无论您是构建动态表单、可重用组件还是管理复杂状态,这些模式都能确保流畅高效的开发体验。

[原文地址](TypeScript Patterns You Should Know for React Development | by Dzmitry Ihnatovich | Medium)

广州有前端坑位滴滴我。

相关推荐
EndingCoder7 小时前
跨平台移动开发框架React Native和Flutter性能对比
flutter·react native·react.js
sunbyte13 小时前
Three.js + React 实战系列 - 职业经历区实现解析 Experience 组件✨(互动动作 + 3D 角色 + 点击切换动画)
javascript·react.js·3d
Python私教15 小时前
使用FastAPI和React以及MongoDB构建全栈Web应用05 FastAPI快速入门
前端·react.js·fastapi
浪裡遊15 小时前
Typescript中的对象类型
开发语言·前端·javascript·vue.js·typescript·ecmascript
从味书16 小时前
安装typescript时,npm install -g typescript报错
javascript·typescript·npm
海绵不是宝宝81716 小时前
React+Springboot项目部署ESC服务器
前端·react.js·前端框架
ZHOU_WUYI16 小时前
React 实现 JWT 登录验证的最小可运行示例
前端·react.js·前端框架
Lysun00117 小时前
electron 结合 react(cra创建的) 创建桌面应用和打包桌面应用
javascript·react.js·electron
Python私教19 小时前
全栈开发实战:FastAPI + React + MongoDB 构建现代Web应用
前端·react.js·fastapi
进取星辰1 天前
21、魔法传送阵——React 19 文件上传优化
前端·react.js·前端框架