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

如何实现泛型组件并允许外部自定义函数获取组件内变量?

How to Convert Your Adder Component into a Generic Component with Customizable Callbacks

Hey there! Let's break down how to turn your Adder component into a flexible generic component that works with any data type, keeps your callbacks returning values ready for downstream processing, and lets other developers customize the onDelete function to access the correct val type.

Step 1: Define a Generic Props Interface

First, we'll create a type-safe props interface using TypeScript generics. This lets the component adapt to any data type T, and ensures callbacks receive the correct value type while allowing flexible return values for downstream handling.

// Define generic props for the Adder component
interface AdderProps<T> {
  // The data value passed to the component, can be any type T
  data: T;
  // onAdd callback: takes a T type value, returns any type (flexible for downstream use)
  onAdd: (val: T) => unknown;
  // onDelete callback: same structure, lets developers customize logic while getting the correct val type
  onDelete: (val: T) => unknown;
}

Step 2: Refactor the Adder Component to Use Generics

Now update your Adder component to accept the generic props. TypeScript will automatically infer the type T based on the data prop passed in, so callbacks get type-safe access to val.

import React from 'react';

// Generic Adder component
const Adder = <T,>(props: AdderProps<T>) => {
  // Example internal handlers that trigger the callbacks
  const handleAddClick = () => {
    // Call onAdd with the typed data, capture the return value for downstream processing
    const addResult = props.onAdd(props.data);
    // You can add logic here to use addResult (e.g., update state, call an API)
  };

  const handleDeleteClick = () => {
    // Call the custom onDelete callback with the typed data
    const deleteResult = props.onDelete(props.data);
    // Similarly, use deleteResult as needed
  };

  return (
    <div className="adder-component">
      <button onClick={handleAddClick}>Add Item</button>
      <button onClick={handleDeleteClick}>Delete Item</button>
    </div>
  );
};

export default Adder;

Step 3: Using the Generic Component (with Custom onDelete)

Other developers can now use the component with any data type, and define a custom onDelete function that gets the correctly typed val out of the box. Here are a couple examples:

Example 1: Using a String Type

const myString = "My Todo Item";

// Custom onDelete that logs the string and returns its length
const customDeleteHandler = (val: string) => {
  console.log(`Deleting item: ${val}`);
  return val.length; // Return value can be used for downstream logic (e.g., update stats)
};

<Adder 
  data={myString} 
  onAdd={(val) => { console.log(val); return val; }} 
  onDelete={customDeleteHandler} 
/>

Example 2: Using a Custom Object Type

// Define a custom data type
interface Product {
  id: number;
  name: string;
  price: number;
}

const myProduct: Product = { id: 123, name: "Laptop", price: 999 };

// Custom onDelete that returns the product ID for API calls
const productDeleteHandler = (val: Product) => {
  console.log(`Deleting product: ${val.name}`);
  return val.id; // Return ID to pass to a delete API endpoint
};

<Adder 
  data={myProduct} 
  onAdd={(val) => { console.log(val); return val; }} 
  onDelete={productDeleteHandler} 
/>

Bonus: Strict Return Type Control (Optional)

If you want to enforce specific return types for the callbacks (e.g., a Promise for async operations), you can extend the props interface with additional generics:

interface AdderProps<T, RAdd = unknown, RDelete = unknown> {
  data: T;
  onAdd: (val: T) => RAdd;
  onDelete: (val: T) => RDelete;
}

// Update the component to use the extended generics
const Adder = <T, RAdd = unknown, RDelete = unknown>(props: AdderProps<T, RAdd, RDelete>) => {
  const handleAddClick = () => {
    const addResult: RAdd = props.onAdd(props.data);
    // If RAdd is a Promise, you can await it here
    if (addResult instanceof Promise) {
      addResult.then(result => console.log("Add completed:", result));
    }
  };
  // ... rest of component
};

This gives you even more control over what the callbacks return, while keeping the component flexible.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:52:42