مقدمه
یکی از اصول اصلی React این است که شما نباید مستقیماً DOM را دستکاری کنید. شما به صورت
«اعلانی» (declarative) به React میگویید که UI باید چگونه باشد و خود React مسئولیت
بهروزرسانی DOM را بر عهده میگیرد. اما گاهی اوقات، ما نیاز داریم که از این مدل اعلانی فرار
کرده و به صورت «دستوری» (imperative) به یک عنصر DOM خاص دسترسی پیدا کنیم.
برای مثال، ممکن است بخواهیم فوکوس را روی یک فیلد ورودی قرار دهیم، یک ویدئو را پخش کنیم، یا
موقعیت اسکرول یک عنصر را مدیریت کنیم. برای این موارد نادر اما ضروری، React یک «دریچه فرار» به
نام «رفرنسها» یا Refs و هوک useRef را فراهم میکند.
useRef چیست؟
هوک useRef یک تابع است که یک شیء قابل تغییر (mutable) را برمیگرداند. این شیء یک پراپرتی به
نام .current دارد که شما میتوانید هر مقداری را در آن ذخیره کنید. این شیء در طول تمام
رندرهای کامپوننت، پایدار باقی میماند.
useRef دو کاربرد اصلی دارد:
- دسترسی به عناصر DOM: شما میتوانید یک ref را به یک عنصر JSX متصل کنید تا یک
ارجاع مستقیم به گره DOM آن در اختیار داشته باشید.
- نگهداری مقادیر قابل تغییر بدون رندر مجدد: شما میتوانید از آن برای ذخیره مقادیری
استفاده کنید که با تغییر آنها، نیازی به رندر مجدد کامپوننت نیست (برخلاف useState).
مثال عملی: فوکوس خودکار روی یک ورودی
بیایید یک مثال کلاسیک را بررسی کنیم: یک کامپوننت که به محض رندر شدن، فوکوس را به صورت خودکار روی
یک فیلد ورودی قرار میدهد.
JAVASCRIPT (React)
import { useRef, useEffect } from 'react';
function FocusInput() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return (
<div>
<p>The input field below should be focused on page load.</p>
<input ref={inputRef} type="text" />
</div>
);
}
مراحل کار با Ref
این کد از سه مرحله اصلی تشکیل شده است:
- ایجاد Ref: ما با فراخوانی useRef(null) یک شیء ref ایجاد میکنیم. مقدار اولیه
null به این معنی است که در ابتدا به هیچ چیزی اشاره نمیکند.
- اتصال Ref: ما این شیء ref را به اتریبیوت خاص ref در عنصر <input> خود پاس
میدهیم. این کار به React میگوید که "لطفاً یک ارجاع به گره DOM واقعی این <input> را
در پراپرتی .current شیء inputRef قرار بده."
- استفاده از Ref: پس از اینکه React کامپوننت را رندر کرده و DOM را ایجاد کرد،
inputRef.current به گره <input> واقعی اشاره خواهد کرد. ما در داخل یک useEffect (با
آرایه وابستگی خالی تا فقط یک بار اجرا شود)، متد بومی DOM یعنی .focus() را روی
inputRef.current فراخوانی میکنیم.
useRef در مقابل useState
درک تفاوت بین این دو هوک بسیار مهم است.
- useState: تغییر مقدار آن با تابع setter یک رندر مجدد را کلید
میزند. از آن برای نگهداری دادههایی استفاده کنید که مستقیماً در UI نمایش داده میشوند.
- useRef: تغییر پراپرتی .current آن، باعث رندر مجدد نمیشود.
از آن برای نگهداری مقادیری استفاده کنید که برای منطق داخلی کامپوننت نیاز دارید اما بر روی
UI تأثیر مستقیم ندارند (مانند ID یک تایمر setInterval) یا برای دسترسی مستقیم به DOM.
در این درس، با هوک useRef به عنوان یک «دریچه فرار» برای دسترسی مستقیم به DOM و نگهداری
مقادیر قابل تغییر بدون ایجاد رندر مجدد آشنا شدیم. این هوک ابزار قدرتمندی برای مدیریت فوکوس،
انیمیشنها و یکپارچهسازی با کتابخانههای DOM-محور است. در درس بعدی، به سراغ هوک useMemo
خواهیم رفت و یاد میگیریم که چگونه با به خاطر سپردن نتایج محاسبات سنگین، از کارهای تکراری
جلوگیری کرده و عملکرد اپلیکیشن خود را بهینه کنیم.