درود دوستان 🤚🏼 من امیررضا ریاحی هستم، نویسندهٔ جدید دیتی. امروز قراره با هم با یکی از مهم‌ترین کانسپت‌های ری‌اکت، به نام کاستوم‌ هوک‌ها آشنا بشیم و یاد بگیریم چجوری یک کاستوم هوک بسازیم و ازش استفاده کنیم. این پست از مجموعه پست‌های ری‌اکت ۱۰۱ هست که شامل مجموعه‌ای از پست‌های کوتاه و کاربردی ری‌اکتی میشه.

 

کاستوم هوک چیه ؟🧐

همونطور که از اسمش پیداست، کاستوم هوک یک هوک شخصی‌سازی و توسعه‌داده‌شده از طرف ماست که کمک می‌کنه از نوشتن کدهای تکراری جلوگیری کنیم باعث که در نتیجه برنامه‌مون رو بهینه‌تر و حرفه‌ای تر می‌کنه. کدهایی که توی یک کاستوم هوک قرار می‌گیره همون کدهای ری‌اکتی هست که توی کامپوننت‌ها می‌نویسیم. اگه توی کامپوننت‌های ما یک قطعه کد (مثل useEffect یا استیت) تکراری داریم، بهتره که اونها رو منتقل کنیم به یک فایل جدا تا به قول معروف Reusability داشته باشیم. برای اینکه ری‌اکت کدهای ما رو بشناسه، می‌بایست اونها رو در قالب یک هوک سازمان‌دهی کنیم. به این هوک‌هایی که خودمون می‌نویسیم می‌گیم Custom Hook.

 

اما چه زمانی باید کاستوم هوک بسازیم و ازش استفاده کنیم؟

بطور کلی، کاستوم هوک‌ها برای این اومدن تا ما از کد تکراری در پروژه‌هامون خودداری کنیم و حرفه‌ای‌تر کد بزنیم. ما می‌تونیم از کاستوم هوک‌ها در عملیات‌هایی مثل fetch یا در localStorage که چندین بار در برنامه از اون‌ها استفاده می‌کنیم، بهره ببریم.

 

چجوری یک کاستوم هوک بسازیم؟🤔

برای اینکه بخواید پوشه‌بندی پروژتون درست و تکمیل باشه، می‌تونید یک فولدر در پوشه src به نام hooks بسازید تا ساختار پروژتون خواناتر و درست‌تر باشه. در پوشه hooks می‌تونید کاستوم هوک‌های خودتون رو قرار بدید. یکی از استانداردهایی که هنگام ساختن هوک‌های باید اون رو رعایت کنیم اینه که اسم یک هوک می‌بایست با کلمه use شروع بشه. برای مثال usePost یا useTheme.

حالا وقتشه یک کامپوننت بسازید و کدنویسی کنید! 😎 مثال ساده یک کاستوم هوک که بررسی می‌کنه کاربر آنلاین هست یا آفلاین :

useOnlineStatus.js :

function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(true);

  useEffect(() => {
    function handleOnline() {
      setIsOnline(true);
    }

    function handleOffline() {
      setIsOnline(false);
    }

    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);

 
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  return isOnline;
}

همونطور که می‌بینید، در این کاستوم هوک ما استیتی برای آنلاین یا آفلاین بودن کاربر تعیین کردیم و با تعریف رویداد، اون رو بروزرسانی کردیم. حالا وقتشه از این کاستوم هوک در پروژمون استفاده کنیم.

App.jsx

import { useOnlineStatus } from './useOnlineStatus.js';

function StatusBar() {
  const isOnline = <<useOnlineStatus();>>
  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

function SaveButton() {
  const isOnline = useOnlineStatus();
}

  function handleSaveClick() {
    console.log('✅ Progress saved');
  }

  return (
    <button disabled={!isOnline} onClick={handleSaveClick}>
      {isOnline ? 'Save progress' : 'Reconnecting...'}
    </button>
  );
}

export default function App() {
  return (
    <>
      <SaveButton />
      <StatusBar />
    </>
  );
}

همونطور که مشاهده می‌کنید، ما با استیتی که در کامپوننت useOnlineStatus ست کردیم، می‌تونیم وضعیت آنلاین بودن کاربر رو بهش نشون بدیم. (این قابلیت رو در خیلی از برنامه‌ها و وبسایت‌ها می‌بینیم. برای مثال، در گوگل کروم وقتی آفلاین می‌شید، بلافاصله پیام "Disconnected" رو مشاهده می‌کنید.)

در اینجا دو نمونه از معروف‌ترین کاستوم هوک هارو براتون نوشتم:

 

کاستوم هوکِ مربوط به سیو کردن مقدار ورودی:

useFormInput.js

import { useState } from 'react';

export function useFormInput(initialValue) {
  const [value, setValue] = useState(initialValue);

  function handleChange(e) {
    setValue(e.target.value);
  }

  const inputProps = {
    value: value,
    onChange: handleChange
  };

  return inputProps;
}

نحوه استفاده از این کامپوننت در App.jsx :

import { useFormInput } from './useFormInput.js';

export default function Form() {
  const firstNameProps = useFormInput('Mary');
  const lastNameProps = useFormInput('Poppins');

  return (
    <>
      <label>
        First name:
        <input {...firstNameProps} />
      </label>
      <label>
        Last name:
        <input {...lastNameProps} />
      </label>
      <p><b>Good morning, {firstNameProps.value} {lastNameProps.value}.</b></p>
    </>
  );
}

و مثال اخر هم یک کاستوم هوک برای ارسال درخواست و بازگردوندن نتیجه درخواست API:

useFetch.js :

import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        const json = await response.json();
        setData(json);
      } catch (e) {
        setError(e);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]);

  return { data, loading, error };
}

نحوه استفاده از این هوک پرکاربرد:

App.jsx :

import React from 'react';
import useFetch from './useFetch';

function App() {
  const { data, loading, error } = <<useFetch('https://api.example.com/data');>>

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {data.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

خیلی راحت تونستیم سه تا از پرکاربردترین کاستوم هوک هارو در ری‌اکت بررسی کنیم و برناممون رو حرفه‌ای تر کنیم .

⚠️ برای مثال های بیشتر میتونین به منبع مراجعه کنین 👇🏼

منبع : 

 

خب دوستان رسیدیم به پایان یکی دیگه از پست های  امیدوارم توضیحات خوانا بوده باشه و یادتون نره اگه سوالی داشتین حتما در قسمت کامنت ها بپرسید قطعا پاسخ خواهم داد (: 🖐🏼