ค้นหาเว็บไซต์

reactjs - ฉันจะใช้ debounce ในเหตุการณ์ onChange ของ Input ใน TypeScript ได้อย่างไร


นี่คือที่ที่ฉันใช้ Debounce

const handleSearch = debounce((value: string) => {
    const filter = tableDataCopy.filter(
      (item) => item[condition].toLowerCase().indexOf(value) !== -1,
    );
    setTableData(filter);
  }, 500);

เหตุการณ์ onChange:

onChange={(e: ChangeEvent<HTMLInputElement>) => handleSearch(e.target.value)}

ฟังก์ชันดีบาวน์:

export function debounce(func: Function, delay: number) {
  let timer: NodeJS.Timeout | null = null;
  return function (this: any) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      func.call(this, ...arguments);
    }, delay);
  };
}

ฉันได้รับข้อผิดพลาดพารามิเตอร์ใน TypeScript :

TS2554: Expected 0 arguments, but got 1.

ฉันรู้ว่านี่ผิดแต่ฉันไม่รู้ว่าจะส่งอาร์กิวเมนต์ใน Debounce อย่างไร

คำตอบ #1

ก่อนอื่น this เป็นอาร์กิวเมนต์ฟังก์ชันพิเศษ มันระบุประเภทที่ต้องการของบริบท (this) ในฟังก์ชัน มันไม่ถือว่าเป็นอาร์กิวเมนต์จริง ซึ่งหมายความว่า function (this: any) {} เป็นฟังก์ชันที่ไม่มีอาร์กิวเมนต์


ประการที่สอง ไม่เคย ใช้คำสำคัญ arguments ใน TypeScript เพราะมันอาจเป็นเรื่องซับซ้อนด้วยหลายสาเหตุ (มันไม่ใช่อาร์เรย์จริง และไม่สามารถระบุชนิดได้เป็นต้น) แทนที่จะใช้ ให้รับ arguments แบบกระจายที่ถูกแมปไปยังตัวแปร

ถูกใจ :

function (...args: string[]) {}

ประการที่สาม Typescript จำเป็นต้องรู้ประเภทฟังก์ชันที่ต้องส่งกลับจาก debounce ของคุณ Function ไม่เพียงพอ มันจำเป็นต้องรู้พารามิเตอร์ที่ฟังก์ชันที่ถูก debounce ของคุณรับ สำหรับสิ่งนี้คุณต้องใช้พารามิเตอร์ประเภททั่วไป

เรื่องนี้ซับซ้อนขึ้นหน่อย

function debounce<
  T extends unknown[]
>(
  func: (...args: T) => void,
  delay: number,
):
  (...args: T) => void
{
  let timer: number | null = null;
  return (...args: T) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      func.call(null, ...args);
    }, delay);
  };
}

นี่คือพารามิเตอร์ทั่วไป:

T extends unknown[]

และใช้มันที่นี่เป็นประเภทอาร์กิวเมนต์ func:

func: (...args: T) => void

และในประเภทการคืนค่าของฟังก์ชัน:

: (...args: T) => void

ตอนนี้ฟังก์ชันที่คุณส่งไปยัง debounce จะมีอาร์กิวเมนต์ที่สังเกตได้โดยพารามิเตอร์ทั่วไป และฟังก์ชันที่ส่งกลับจะมีอาร์กิวเมนต์เหมือนกันเป๊ะ


สุดท้าย คุณไม่จำเป็นต้องระบุประเภทของเหตุการณ์ใน onChange React รู้จักประเภทขององค์ประกอบ ดังนั้น TypeScript สามารถรู้ประเภทของอาร์กิวเมนต์ได้

<input type="text" onChange={e => handleSearch(e.target.value)} />

ตัวอย่างการทำงานบนสนามเด็กเล่น TypeScript

บทความที่เกี่ยวข้อง