ทำระบบค้นหา ด้วยเทคนิค Debounce ใน React ด้วย useSWR

Aug. 22, 2024 · boychawin

สวัสดีครับ วันนี้จะพาใช้เทคนิค Debounce ช่วยในการทำระบบค้นหาครับ โดยเฉพาะมือใหม่ๆ ในการค้นหาข้อมูลแบบเรียลไทม์ การควบคุมการเรียก API เพื่อป้องกันการร้องขอข้อมูลที่มากเกินไปเป็นสิ่งสำคัญม!!! หนึ่งในวิธีที่ใช้บ่อยในการแก้ปัญหานี้คือการใช้ "Debounce" ซึ่งจะช่วยให้ระบบทำการค้นหาเมื่อผู้ใช้หยุดพิมพ์ไปสักระยะหนึ่ง บทความนี้จะแนะนำการใช้ Debounce ร่วมกับ useSWR ใน React เพื่อสร้างการค้นหาที่มีประสิทธิภาพขึ้นไปอีก

1. สร้างฟังก์ชัน Debounce (น่าจะมี swr กันแล้วนะครับ)

ฟังก์ชัน debounce จะช่วยชะลอการทำงานของฟังก์ชันที่ถูกเรียกใช้หลายครั้งติดกันในระยะเวลาสั้นๆ โดยจะทำงานหลังจากหยุดการเรียกใช้งานไปช่วงหนึ่งเท่านั้น


function debounce<T extends (...args: any[]) => void>(func: T, delay: number) {
  let timeoutId: NodeJS.Timeout;
  return (...args: Parameters<T>) => {
    if (timeoutId) clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func(...args), delay);
  };
}

2. การใช้ useSWR และ debounce ร่วมกันใน React


import React, { useState } from 'react';
import useSWR from 'swr';
import { getData } from 'your-data-fetching-service'; // Replace with your actual import

const MyComponent = () => {

  const [search, setSearch] = React.useState<string | null>('');
  const [searchShow, setSearchShow] = React.useState<string | null>('');

  const [skip, setSkip] = useState(0);
  const [take, setTake] = useState(10);

  const { data: repositories, isLoading, error }: any = useSWR(
    `medicine-warehouse/getMWProductList?skip=${skip}&take=${take}&search=${search}`,
    async (key: string) => await getData(key)
  );

  const { data } = repositories || {}
  
  const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    setSearchShow(value);
    debounceHandleSearch(e);
  };

  const debounceHandleSearch = debounce((e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    setSearch(value);
    console.log(value)
  }, 500);

  return (
    <div>
      <input type="text" onChange={handleSearch} value={searchShow} placeholder="Search..." />
      {isLoading && <p>Loading...</p>}
      {error && <p>Error loading data.</p>}
      {data && (
        <ul>
          {data.map((repo: any) => (
            <li key={repo.id}>{repo.name}</li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default MyComponent;

การอธิบายโค้ด

  • การตั้งค่า State: เราใช้ useState เพื่อจัดการสถานะของ search, skip และ take ซึ่งเป็นตัวแปรที่ใช้ในการควบคุมการดึงข้อมูลจาก API

  • การใช้ useSWR: useSWR จะดึงข้อมูลจาก API โดยใช้พารามิเตอร์ที่เราตั้งไว้ โดยที่การดึงข้อมูลจะเกิดขึ้นเมื่อใดก็ตามที่ search, skip หรือ take มีการเปลี่ยนแปลง

  • การใช้ debounce: ฟังก์ชัน handleSearch จะทำงานเมื่อมีการพิมพ์ในช่องค้นหา แต่การอัพเดทสถานะ search จะเกิดขึ้นหลังจากที่ผู้ใช้หยุดพิมพ์ไป 500 มิลลิวินาที ทำให้การเรียก API ไม่เกิดขึ้นบ่อยเกินไป

ข้อดี

  • ประสิทธิภาพในการดึงข้อมูล: ลดจำนวนการเรียก API ที่ไม่จำเป็น โดยเฉพาะอย่างยิ่งเมื่อผู้ใช้พิมพ์ในช่องค้นหาอย่างต่อเนื่อง

  • การตอบสนองที่รวดเร็ว: ผู้ใช้จะได้รับประสบการณ์การใช้งานที่ดียิ่งขึ้น เนื่องจากระบบจะไม่ทำงานช้าลงเพราะมีการเรียก API มากเกินไป

  • การเขียนโค้ดที่สะอาดและง่ายต่อการดูแลรักษา: การใช้ useSWR และ debounce ทำให้โค้ดกระชับและง่ายต่อการทำความเข้าใจ

ข้อเสีย

  • ความซับซ้อนในการตั้งค่า: การใช้ debounce และ useSWR ร่วมกันอาจทำให้โค้ดมีความซับซ้อนเพิ่มขึ้นสำหรับนักพัฒนาที่ไม่มีประสบการณ์

สรุป

การใช้ debounce ร่วมกับ useSWR ในการสร้างฟังก์ชันค้นหาใน React เป็นอีกวิธีที่มีประสิทธิภาพในการจัดการการเรียก API ในแอปพลิเคชันที่มีการค้นหาข้อมูลแบบเรียลไทม์ ข้อดีหลักคือการลดจำนวนการเรียก API ที่ไม่จำเป็น