أطلق العنان لقوة createRef في React للوصول المباشر إلى DOM والتفاعل مع المكونات. يقدم هذا الدليل أمثلة عملية وأفضل الممارسات للمطورين حول العالم.
إتقان createRef في React: دليل شامل للتطوير الحديث
في عالم تطوير الواجهات الأمامية الديناميكي، تبرز React كمكتبة جافاسكريبت قوية ومتعددة الاستخدامات لبناء واجهات المستخدم. إحدى الميزات الرئيسية التي تسمح لمطوري React بالتفاعل مباشرة مع نموذج كائن المستند (DOM) وإدارة سلوك المكونات هي واجهة برمجة التطبيقات createRef
. يتعمق هذا الدليل في تعقيدات createRef
، موفرًا فهمًا شاملاً لاستخدامها وفوائدها وأفضل الممارسات للمطورين في جميع أنحاء العالم.
فهم مراجع React (Refs)
قبل الخوض في createRef
، من الضروري فهم مفهوم المراجع (refs) في React. يوفر المرجع طريقة للوصول إلى عُقد DOM أو عناصر React التي تم إنشاؤها في دالة العرض (render). يتيح لك هذا الوصول إجراء عمليات مثل التركيز على حقل إدخال، أو تشغيل الرسوم المتحركة، أو قياس حجم عنصر ما.
على عكس التلاعب التقليدي بـ DOM في جافاسكريبت، توفر المراجع في React طريقة متحكم بها وفعالة للتفاعل مع DOM. يقوم DOM الافتراضي في React بتجريد العديد من تعقيدات التلاعب المباشر بـ DOM، لكن المراجع توفر جسرًا عند الضرورة للوصول المباشر.
تقديم createRef
createRef
هي دالة توفرها React لإنشاء كائن مرجعي (ref object). يحتوي هذا الكائن المرجعي على خاصية current
التي تحمل عقدة DOM أو نسخة مكون React الذي يرتبط به المرجع. تم تقديم واجهة createRef
كجزء من React 16.3 وهي الطريقة الموصى بها لإنشاء المراجع في مكونات الصنف (class components). بالنسبة للمكونات الوظيفية، يوفر useRef
(وهو خطاف من React) وظائف مماثلة.
إنشاء كائن مرجعي
لإنشاء كائن مرجعي، ما عليك سوى استدعاء الدالة createRef()
:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return (
);
}
}
في هذا المثال، this.myRef
هو كائن مرجعي يتم تعيينه لخاصية ref
لعنصر الإدخال. ستحتوي خاصية current
لـ this.myRef
على مرجع لعنصر الإدخال بعد تحميل المكون.
الوصول إلى عقدة DOM
بمجرد تحميل المكون، يمكنك الوصول إلى عقدة DOM من خلال خاصية current
للكائن المرجعي:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.focusInput = this.focusInput.bind(this);
}
componentDidMount() {
this.focusInput();
}
focusInput() {
this.myRef.current.focus();
}
render() {
return (
);
}
}
في هذا المثال، تستخدم دالة focusInput
this.myRef.current
للوصول إلى عنصر الإدخال واستدعاء دالة focus()
الخاصة به. سيؤدي هذا إلى التركيز تلقائيًا على حقل الإدخال عند تحميل المكون.
حالات استخدام createRef
تعتبر createRef
ذات قيمة في سيناريوهات مختلفة حيث يكون التلاعب المباشر بـ DOM أو الوصول إلى نُسخ المكونات مطلوبًا. إليك بعض حالات الاستخدام الشائعة:
- التركيز على حقول الإدخال النصية: كما هو موضح في المثال السابق، تُستخدم
createRef
بشكل شائع للتركيز على حقول الإدخال النصية برمجيًا. هذا مفيد لتحسين تجربة المستخدم عن طريق التركيز التلقائي على حقل الإدخال الأول في النموذج، أو التركيز على حقل إدخال بعد إجراء معين. - إدارة تشغيل الوسائط: يمكن استخدام المراجع للتحكم في عناصر الوسائط مثل
<video>
أو<audio>
. يمكنك استخدام المراجع لتشغيل الوسائط أو إيقافها مؤقتًا أو ضبط مستوى الصوت. على سبيل المثال:import React from 'react'; class VideoPlayer extends React.Component { constructor(props) { super(props); this.videoRef = React.createRef(); this.playVideo = this.playVideo.bind(this); } playVideo() { this.videoRef.current.play(); } render() { return (
- تشغيل الرسوم المتحركة: يمكن استخدام المراجع للوصول إلى عناصر DOM وتشغيل الرسوم المتحركة باستخدام جافاسكريبت أو CSS. يتيح لك ذلك إنشاء رسوم متحركة معقدة وتفاعلية تستجيب لإجراءات المستخدم.
import React from 'react'; class AnimatedBox extends React.Component { constructor(props) { super(props); this.boxRef = React.createRef(); this.animate = this.animate.bind(this); } animate() { const box = this.boxRef.current; box.classList.add('animate'); } render() { return (
في هذا المثال، سيؤدي النقر على الزر إلى إضافة الصنف
animate
إلى عنصر الصندوق، مما يؤدي إلى تشغيل حركة CSS. - قياس حجم وموضع العنصر: المراجع مفيدة للحصول على حجم وموضع عناصر DOM. يمكن استخدام هذه المعلومات لحسابات التخطيط، أو التنسيق الديناميكي، أو إنشاء عناصر تفاعلية.
import React from 'react'; class SizeReporter extends React.Component { constructor(props) { super(props); this.elementRef = React.createRef(); this.state = { width: 0, height: 0 }; this.reportSize = this.reportSize.bind(this); } componentDidMount() { this.reportSize(); } reportSize() { const element = this.elementRef.current; this.setState({ width: element.offsetWidth, height: element.offsetHeight }); } render() { return (
Width: {this.state.width}px, Height: {this.state.height}px
يبلغ هذا المكون عن عرض وارتفاع الـ div بعد تحميله.
- التكامل مع مكتبات الطرف الثالث: غالبًا ما تُستخدم المراجع لدمج مكونات React مع مكتبات الطرف الثالث التي تتطلب وصولاً مباشرًا إلى DOM. على سبيل المثال، قد تستخدم مرجعًا للوصول إلى عنصر DOM وتهيئة مكون إضافي من jQuery عليه.
import React from 'react'; import $ from 'jquery'; class MyComponent extends React.Component { constructor(props) { super(props); this.elementRef = React.createRef(); } componentDidMount() { $(this.elementRef.current).plugin(); // Initialize jQuery plugin } render() { return ; } }
createRef
مقابل مراجع رد النداء (Callback Refs)
قبل تقديم createRef
، كانت مراجع رد النداء (callback refs) طريقة شائعة للوصول إلى عُقد DOM في React. على الرغم من أن مراجع رد النداء لا تزال صالحة، إلا أن createRef
تقدم نهجًا أكثر وضوحًا وأقل تعقيدًا، خاصة في مكونات الصنف.
مرجع رد النداء هو دالة تستدعيها React مع عقدة DOM أو نسخة المكون كوسيط. تقوم بتعيين هذه الدالة لخاصية ref
لعنصر ما:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = null;
this.setRef = element => {
this.myRef = element;
};
}
componentDidMount() {
if (this.myRef) {
this.myRef.focus();
}
}
render() {
return ;
}
}
على الرغم من أن هذا النهج يعمل، إلا أنه قد يكون أكثر تعقيدًا في الإدارة، خاصة عند التعامل مع مراجع متعددة. تبسط createRef
هذه العملية من خلال توفير كائن مرجعي مخصص.
الفروق الرئيسية:
- القابلية للقراءة: يُعتبر
createRef
بشكل عام أكثر قابلية للقراءة وأسهل في الفهم. - الاتساق: يوفر
createRef
طريقة متسقة لإنشاء المراجع والوصول إليها. - الأداء: في بعض الحالات، يمكن أن تسبب مراجع رد النداء عمليات إعادة عرض غير ضرورية لأن دالة رد النداء هي دالة جديدة في كل عملية عرض. تتجنب
createRef
هذه المشكلة.
أفضل الممارسات لاستخدام createRef
لضمان الأداء الأمثل وقابلية الصيانة، اتبع أفضل الممارسات التالية عند استخدام createRef
:
- استخدم
createRef
في مكونات الصنف: تم تصميمcreateRef
للاستخدام في مكونات الصنف. بالنسبة للمكونات الوظيفية، استخدم خطافuseRef
. - تجنب الإفراط في استخدام المراجع: يجب استخدام المراجع باعتدال. يمكن أن يؤدي الإفراط في استخدامها إلى كود يصعب صيانته وفهمه. فضل النهج التصريحي كلما أمكن ذلك.
- التحقق من القيم الفارغة (Null Checks): تحقق دائمًا مما إذا كانت خاصية
current
للمرجع فارغة (null) قبل الوصول إليها، خاصة في دالة دورة الحياةcomponentDidMount
. قد لا تكون عقدة DOM متاحة فور تحميل المكون.componentDidMount() { if (this.myRef.current) { this.myRef.current.focus(); } }
- تجنب تعديل DOM مباشرة: بينما توفر المراجع الوصول إلى DOM، تجنب تعديل DOM مباشرة إلا في حالة الضرورة القصوى. يوفر DOM الافتراضي في React طريقة فعالة لتحديث واجهة المستخدم، ويمكن أن يتعارض التلاعب المباشر بـ DOM مع عملية العرض في React.
- تنظيف المراجع عند الضرورة: في بعض الحالات، قد تحتاج إلى تنظيف المراجع عند إلغاء تحميل المكون. هذا مهم بشكل خاص عند التعامل مع مكتبات الطرف الثالث التي قد تحتفظ بمراجع لعناصر DOM.
createRef
في المكونات الوظيفية مع Hooks
بينما يُستخدم createRef
بشكل أساسي في مكونات الصنف، يمكن للمكونات الوظيفية تحقيق وظائف مماثلة باستخدام خطاف useRef
. يعيد useRef
كائنًا مرجعيًا قابلاً للتغيير تتم تهيئة خاصية .current
الخاصة به بالقيمة الأولية (initialValue
) التي تم تمريرها. سيستمر الكائن المُعاد طوال عمر المكون.
import React, { useRef, useEffect } from 'react';
function MyFunctionalComponent() {
const inputRef = useRef(null);
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, []);
return ;
}
في هذا المثال، يقوم useRef(null)
بإنشاء كائن مرجعي يتم تعيينه للمتغير inputRef
. يتم استخدام خطاف useEffect
للتركيز على حقل الإدخال بعد عرض المكون. تضمن مصفوفة الاعتماديات الفارغة []
أن يتم تشغيل التأثير مرة واحدة فقط، بعد العرض الأولي.
حالات استخدام متقدمة واعتبارات
بالإضافة إلى حالات الاستخدام الأساسية، يمكن استخدام createRef
في سيناريوهات أكثر تقدمًا:
- إعادة توجيه المراجع (Forwarding Refs): توفر React آلية تسمى
React.forwardRef
تسمح لك بتمرير مرجع عبر مكون إلى أحد أبنائه. هذا مفيد عندما تحتاج إلى الوصول إلى عقدة DOM داخل مكون ابن من مكون أب.import React, { forwardRef } from 'react'; const FancyInput = forwardRef((props, ref) => ( )); class ParentComponent extends React.Component { constructor(props) { super(props); this.inputRef = React.createRef(); } componentDidMount() { this.inputRef.current.focus(); } render() { return
; } } في هذا المثال، يستخدم مكون
FancyInput
forwardRef
لتمرير المرجع إلى عنصر الإدخال الأساسي. يمكن لمكونParentComponent
بعد ذلك الوصول إلى عنصر الإدخال والتلاعب به من خلال المرجع. - المكونات عالية الرتبة (HOCs): عند استخدام المكونات عالية الرتبة (HOCs)، قد تحتاج إلى التعامل مع المراجع بعناية. إذا كان HOC يغلف مكونًا يستخدم المراجع، فأنت بحاجة إلى التأكد من إعادة توجيه المراجع بشكل صحيح.
import React, { forwardRef } from 'react'; function withRef(WrappedComponent) { const WithRef = forwardRef((props, ref) => { return
; }); WithRef.displayName = `withRef(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`; return WithRef; } class MyComponent extends React.Component { render() { return My Component; } } const EnhancedComponent = withRef(MyComponent); - العرض من جانب الخادم (SSR): عند استخدام العرض من جانب الخادم، كن على علم بأن المراجع قد لا تكون متاحة أثناء العرض الأولي على الخادم. هذا لأن DOM غير متاح على الخادم. يجب عليك فقط الوصول إلى المراجع بعد تحميل المكون على العميل.
الخاتمة
createRef
هي أداة قوية للوصول إلى عُقد DOM ونُسخ المكونات في React. من خلال فهم استخدامها وفوائدها وأفضل الممارسات، يمكنك الاستفادة بشكل فعال من المراجع لبناء واجهات مستخدم أكثر تفاعلية وديناميكية. سواء كنت تركز على حقول الإدخال النصية، أو تدير تشغيل الوسائط، أو تتكامل مع مكتبات الطرف الثالث، فإن createRef
توفر طريقة متحكم بها وفعالة للتفاعل مع DOM.
تذكر استخدام createRef
بحكمة، مفضلاً النهج التصريحي كلما أمكن ذلك. باتباع الإرشادات الموضحة في هذا الدليل، يمكنك التأكد من أن تطبيقات React الخاصة بك تتمتع بالأداء العالي وقابلية الصيانة والتوسع.
بينما تواصل رحلتك مع React، سيثبت إتقان createRef
بلا شك أنه مهارة قيمة في مجموعة أدوات التطوير الخاصة بك. استمر في التجربة، واستكشاف حالات الاستخدام المختلفة، وصقل فهمك لهذه الميزة الأساسية في React.