การสร้าง Loader ใน React ด้วย Context API และ SWR

Oct. 27, 2024 · boychawin

ในบทความนี้ ผมจะพูดถึงวิธีการสร้าง loader ที่แสดงสถานะการโหลดในแอปพลิเคชัน React ของเรา โดยใช้ Context API ร่วมกับ SWR (stale-while-revalidate) สำหรับการดึงข้อ ซึ่งจะช่วยให้ผู้ใช้เห็นข้อความที่บอกว่า "กรุณารอสักครู่" ขณะที่ข้อมูลกำลังโหลดอยู่หรือจะเอาไปประยุกต์ใช้งานในส่วนอื่นๆก็ได้ครับ

1. สร้าง Loader ด้วย Context

เราจะเริ่มด้วยการสร้าง Context สำหรับการจัดการสถานะการโหลด ซึ่งจะช่วยให้เราสามารถแชร์ข้อมูลระหว่างคอมโพเนนต์ได้อย่างสะดวก

// LoaderContext.tsx
import React, { createContext, useContext, useState, ReactNode } from 'react';

interface LoaderContextType {
  isLoading: boolean;
  showLoading: () => void;
  hideLoading: () => void;
}

const LoaderContext = createContext<LoaderContextType | undefined>(undefined);

interface LoaderProviderProps {
  children: ReactNode;
}

export const LoaderProvider: React.FC<LoaderProviderProps> = ({ children }) => {
  const [isLoading, setIsLoading] = useState<boolean>(false);

  const showLoading = () => setIsLoading(true);
  const hideLoading = () => setIsLoading(false);

  return (
    <LoaderContext.Provider value={{ isLoading, showLoading, hideLoading }}>
      {children}
    </LoaderContext.Provider>
  );
};

export const useLoader = (): LoaderContextType => {
  const context = useContext(LoaderContext);
  if (!context) {
    throw new Error('useLoader ต้องถูกใช้ภายใน LoaderProvider');
  }
  return context;
};

2. สร้าง Custom Loader Component

หลังจากที่เราสร้าง Context แล้ว ต่อไปเราจะสร้างคอมโพเนนต์ที่ใช้แสดง loader โดยจะใช้ CSS เพื่อให้ loader อยู่กึ่งกลางหน้าจอ

// CustomLoaderBackdrop.tsx
import React from 'react';
import { useLoader } from './LoaderContext';
import './CustomLoaderBackdrop.css';

const CustomLoaderBackdrop: React.FC = () => {
  const { isLoading } = useLoader();

  return isLoading ? (
    <div className="overlay">
      <div className="spanner">
        <div className="loader"></div>
        <p>กรุณารอสักครู่</p>
      </div>
    </div>
  ) : null;
};

export default CustomLoaderBackdrop;

3. กำหนด CSS สำหรับ Loader

เพื่อให้ loader ดูดีและอยู่ตรงกลาง เราจะใช้ CSS ดังนี้

/* CustomLoaderBackdrop.css */
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.spanner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  color: #fff;
}

.loader {
  border: 4px solid #f3f3f3;
  border-radius: 50%;
  border-top: 4px solid #189A92;
  width: 40px;
  height: 40px;
  animation: spin 1s linear infinite;
  margin-bottom: 10px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

4. ใช้งาน Loader ร่วมกับ SWR

เราจะใช้ SWR สำหรับการดึงข้อมูลในคอมโพเนนต์ของเรา และเรียกใช้ loader ตามสถานะการโหลด

// App.tsx หรือ layout.tsx
import React, { useEffect } from 'react';
import useSWR from 'swr';
import { useLoader } from './LoaderContext';
import CustomLoaderBackdrop from './CustomLoaderBackdrop';

const AppContent: React.FC = () => {

  const { showLoading, hideLoading } = useLoader();

  const { data, isLoading }: any = useSWR(
    `...`,
    getDataOld
  );

  useEffect(() => {
    isLoading ? showLoading() : hideLoading();
  }, [isLoading, showLoading, hideLoading]);

  return (
    <LoaderProvider>
      <CustomLoaderBackdrop />
    </LoaderProvider>
  );
};
export default AppContent;

สรุป

ในบทความนี้เราได้เรียนรู้การสร้าง loader ที่แสดงสถานะการโหลดใน React โดยใช้ Context API และ SWR สำหรับการดึงข้อมูล การแสดง loader ช่วยให้แอปพลิเคชันของเราดูเป็นมืออาชีพครับ