useRef في React: التعامل مع DOM والقيم بدون رندر

أحيانًا تحتاج الوصول لعنصر DOM مباشرة أو حفظ قيمة بدون إعادة رندر. هنا يأتي دور useRef.

ما هو useRef في React؟

useRef هو Hook يوفر لك كائنًا ثابتًا يحتوي على خاصية current. يمكن استخدامه للوصول إلى DOM أو حفظ قيمة لا تتسبب في إعادة رندر.

التعريف البسيط: useRef = صندوق لحفظ قيمة أو عنصر DOM عبر الرندرات.

مثال 1: الوصول إلى DOM (focus على input)

import { useRef } from "react";

function FocusInput() {
  const inputRef = useRef(null);

  function handleFocus() {
    inputRef.current.focus();
  }

  return (
    <div>
      <input ref={inputRef} placeholder="اكتب هنا" />
      <button onClick={handleFocus}>تركيز</button>
    </div>
  );
}

ربطنا الـ ref بالـ input، ثم استخدمنا focus() عند الضغط على الزر.

لماذا نحتاج هذا؟ لأن بعض التفاعلات تتطلب التعامل مع DOM مباشرة، مثل التركيز على حقل أو تحديد النص. useRef يوفّر طريقًا آمنًا للوصول للعنصر بدون كسر طريقة React في التحكم بالواجهة.

خطوة بخطوة: عند الضغط على الزر، تُستدعى دالة handleFocus، ثم نصل إلى العنصر عبر inputRef.current وننفّذ focus(). بدون ref لن تستطيع الوصول إلى عنصر DOM داخل React بشكل مباشر.

مثال 2: حفظ قيمة بدون إعادة رندر

import { useRef, useState } from "react";

function ClickCounter() {
  const countRef = useRef(0);
  const [renderCount, setRenderCount] = useState(0);

  function handleClick() {
    countRef.current += 1;
    setRenderCount((c) => c + 1);
  }

  return (
    <div>
      <p>عدد النقرات (ref): {countRef.current}</p>
      <p>عدد الرندرات: {renderCount}</p>
      <button onClick={handleClick}>انقر</button>
    </div>
  );
}

هنا زدنا countRef.current بدون أن نجبر React على إعادة رندر. لاحظ أن الرندر يحدث فقط بسبب setRenderCount.

هذا المثال يوضح الفرق بين useRef و useState: ref يحفظ القيمة لكن لا يحدّث الواجهة تلقائيًا، بينما state يسبب إعادة رندر لتحديث العرض.

لماذا أضفنا renderCount؟ فقط لإثبات أن تغيير ref وحده لا يسبب إعادة رندر. لذلك نستخدم setRenderCount لإجبار الواجهة على التحديث حتى نرى القيمة الجديدة في الشاشة.

مثال 3: تخزين معرف مؤقت (setInterval)

import { useEffect, useRef } from "react";

function Timer() {
  const intervalRef = useRef(null);

  useEffect(() => {
    intervalRef.current = setInterval(() => {
      console.log("يعمل...");
    }, 1000);

    return () => clearInterval(intervalRef.current);
  }, []);

  return <p>Timer شغال</p>;
}

استخدمنا ref لتخزين رقم المؤقت حتى نوقفه عند التنظيف.

لو لم نخزّن معرف المؤقت في ref، فلن نستطيع الوصول إليه لاحقًا داخل cleanup. استخدام ref هنا يحافظ على قيمة واحدة ثابتة بين الرندرات.

هذه الحالة شائعة مع setInterval و setTimeout: تريد بدء مؤقت عند التحميل وإيقافه عند إزالة المكوّن. ref يسمح لك بتخزين المعرّف والوصول إليه في أي وقت.

متى تستخدم useRef؟

  • عندما تحتاج الوصول إلى DOM مباشرة.
  • عندما تحتاج حفظ قيمة بين الرندرات بدون إعادة رندر.
  • لتخزين مؤقتات أو اشتراكات.

أخطاء شائعة

  • استخدام useRef بدل useState في حالة تحتاج عرضها في الواجهة.
  • تغيير ref وتوقع إعادة رندر (لن يحدث).

الأسئلة الشائعة — FAQ

ما هو useRef في React؟

Hook يسمح بالوصول إلى DOM أو حفظ قيمة لا تسبب إعادة رندر.

متى أستخدم useRef بدل useState؟

عندما تحتاج حفظ قيمة بين الرندرات بدون تحديث الواجهة.

هل useRef يسبب إعادة رندر؟

لا، تغيير قيمة ref لا يسبب إعادة رندر.

كيف أعمل focus على input باستخدام useRef؟

اربط ref بالـ input ثم استدعِ ref.current.focus().

ما معنى ref.current؟

هي القيمة الحالية المخزنة داخل الـ ref.

التالي: سننتقل لدرس useMemo & useCallback لتحسين الأداء.
المحرر الذكي

اكتب الكود وشاهد النتيجة فوراً

جرب الآن مجاناً
قناة ديف عربي

تابع أحدث الدروس والتحديثات مباشرة على واتساب

انضم الآن