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

TypeScript与Fetch结合优化:React中复用Pokemon数据转换逻辑

抽离Pokemon表单数据转API格式的重复逻辑

当然可以用Object.keys().reduce把转换逻辑抽离到独立文件里,彻底消除创建和更新操作的代码重复。下面是具体实现步骤:


1. 抽离转换逻辑到工具函数

新建一个工具文件(比如src/utils/apiTransform.ts),把abilities转IRI数组的逻辑封装成通用函数:

// src/utils/apiTransform.ts
import type { PokemonFormData, ApiPokemon } from '../types';

export const transformPokemonForApi = (formData: PokemonFormData): ApiPokemon => {
  return Object.keys(formData).reduce((apiData, key) => {
    const fieldKey = key as keyof PokemonFormData;
    
    // 处理关联字段:将abilities转换为API所需的IRI数组
    if (fieldKey === 'abilities') {
      apiData.abilities = formData[fieldKey].map(ability => `/api/abilities/${ability.id}`);
    } else {
      // 普通字段直接映射
      apiData[fieldKey as keyof ApiPokemon] = formData[fieldKey] as any;
    }
    
    return apiData;
  }, {} as ApiPokemon);
};

2. 定义对应的TypeScript类型

在src/types/index.ts里明确表单数据和API数据的类型,保证类型安全:

// src/types/index.ts
// 前端表单收集的数据结构
export interface PokemonFormData {
  name: string;
  abilities: Array<{ id: number; name: string }>;
  // 其他字段(比如身高、体重等)按需添加
}

// API平台接受的数据结构
export interface ApiPokemon {
  name: string;
  abilities: string[]; // 存储技能的IRI字符串数组
  // 其他字段和表单对应
}

3. 在创建/更新函数中复用工具函数

现在创建和更新Pokemon的代码可以简化成:

// 创建Pokemon
const createPokemon = async (formData: PokemonFormData) => {
  const apiData = transformPokemonForApi(formData);
  
  const res = await fetch('/api/pokemons', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(apiData),
  });

  if (!res.ok) throw new Error('创建Pokemon失败');
  return res.json();
};

// 更新Pokemon
const updatePokemon = async (pokemonId: number, formData: PokemonFormData) => {
  const apiData = transformPokemonForApi(formData);
  
  const res = await fetch(`/api/pokemons/${pokemonId}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(apiData),
  });

  if (!res.ok) throw new Error('更新Pokemon失败');
  return res.json();
};

扩展说明

如果以后需要处理其他关联字段(比如Pokemon的属性types),只需要在transformPokemonForApi的reduce逻辑里加一个判断分支即可,完全不用修改创建/更新的业务代码,扩展性很强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:30:03