createRoot
تمكنك createRoot
من إنشاء نقطة بداية أو جذر (Root) لعرض مكونات React داخل عنصر DOM في المتصفح.
const root = createRoot(domNode, options?)
المرجع
createRoot(domNode, options?)
استدعِ createRoot
لإنشاء جذر React لعرض المحتوى داخل عنصر DOM في المتصفح.
import { createRoot } from 'react-dom/client';
const domNode = document.getElementById('root');
const root = createRoot(domNode);
سيقوم React بإنشاء جذر لـ domNode
، ويتولى إدارة العنصر DOM داخله. بعد إنشاء الجذر، يتعين عليك استدعاء root.render
لعرض مكون React داخله:
root.render(<App />);
يتم عادة إنشاء التطبيق بالكامل باستخدام React بنداء واحد فقط لـ createRoot
في المكون الجذر. قد يحتوي الموقع الذي يستخدم React لأجزاء محددة من الصفحة على عدد من نقاط البداية الفردية حسب الحاجة.
المعاملات
-
domNode
: عنصر DOM يقوم React بإنشاء جذر لهذا العنصر ويتيح لك استدعاء الدوال على الجذر مثلrender
لعرض المحتوى الذي تنشئه React. -
options
اختياري: كائن يحتوي على خيارات لجذر React هذا.onRecoverableError
اختياري: دالة مرجعية تُستدعى تلقائيًا عندما يفيق React من الأخطاء.identifierPrefix
اختياري: بادئة نصيّة يستخدمها React للمعرفات الفريدة التي تنشأ عن طريقuseId
. مفيد لتجنب التعارض عند استخدام العديد من الجذور في نفس الصفحة.
العائدات
يعيد createRoot
كائنًا يحتوي على طريقتين: render
و unmount
.
ملاحظات
- إذا كان تطبيقك يتم عرضه من الخادم SSR، فإن استخدام
createRoot()
غير مدعوم. استخدمhydrateRoot()
بدلاً من ذلك. - من المرجح أن لديك استدعاء واحد فقط لـ
createRoot
في تطبيقك. إذا كنت تستخدم إطار عمل، فقد يستدعيها الإطار نيابةً عنك. - عندما ترغب في عرض جزء من JSX في جزء آخر من شجرة DOM التي ليست طفلًا للمكون الخاص بك (على سبيل المثال، نافذة محادثة، أو توضيح Tooltip)، استخدم
createPortal
بدلاً منcreateRoot
.
root.render(reactNode)
استدعِ root.render
لعرض جزء من JSX (“عنصر React”) داخل عنصر DOM في جذر React.
root.render(<App />);
سيعرض React <App />
في الجذر، وسيتولى إدارة العنصر DOM داخله.
المعاملات
reactNode
: عنصر React الذي ترغب في عرضه. عادةً ما يكون هذا جزءًا من JSX مثل<App />
، ولكن يمكنك أيضًا تمرير عنصر React المُنشأ باستخدامcreateElement()
، أو نص أو رقم أوnull
أوundefined
.
العائدات
يعيد root.render
undefined
.
ملاحظات
-
عندما تستدعي
root.render
للمرة الأولى، سيحذف React كل المحتوى الموجود داخل جذر React قبل عرض مكونات React فيه. -
إذا كان جذر عنصر DOM الخاص بك يحتوي على HTML أنشأته React على الخادم أو أثناء البناء، استخدم
hydrateRoot()
بدلاً من ذلك، والتي تربط مستمعي الأحداث بـ HTML الموجود بالفعل. -
إذا استدعيت
render
في نفس الجذر أكثر من مرة، ستحدث React عناصر DOM اللازمة ليظهر أحدث JSX مررتها، ستقرر React أي أجزاء React يمكن إعادة استخدامها، ,أيها يحتاج لإعادة الإنشاء عن طريق “مطابقتها” مع الشجرة المعروضة سابقًا. استدعاءrender
في نفس الجذر مرة أخرى يشبه مناداة دالةset
في المكون الجذر: تتجنب React تحديثات DOM غير الضرورية.
root.unmount()
استدعِ root.unmount
لتدمير شجرة معروضة داخل جذر React.
root.unmount();
عادةً، لن يستدعي تطبيق مبني كاملًا بـ React root.unmount
.
هذا يكون مفيدًا بشكل أساسي إذا كان عنصر جذر React الخاصة بك (أو أي من العناصر الأسلاف لها) قد يتم إزالتها من DOM بواسطة بعض الأكواد الأخرى. على سبيل المثال، تخيل أن لديك لوحة علامات jQuery تقوم بإزالة علامات غير نشطة من DOM. إذا تمت إزالة علامة ما، فإن كل ما بداخلها (بما في ذلك جذور React الداخلية) سيتم إزالته من DOM أيضًا. في هذه الحالة، تحتاج إلى إخبار React بأنه يجب “إيقاف” إدارة محتوى الجذر المزال عن طريق استدعاء root.unmount
. وإلا، فإن المكونات الداخلية في الجذر المزال لن تعرف كيفية التنظيف وتحرير الموارد العامة مثل الاشتراكات.
عند استدعاء root.unmount
، سيتم إلغاء تثبيت جميع المكونات في الجذر” و”فصل” React عن عنصر DOM الجذر، بما في ذلك إزالة أي معالجات أحداث أو حالة في الشجرة.
المعاملات
root.unmount
لا تستقبل أي معاملات.
العائدات
تعيد root.unmount
: undefined
.
ملاحظات
- استدعاء
root.unmount
سيلغي تثبيت جميع المكونات في الشجرة ويفصل React عن عنصر DOM الجذر. - بمجرد استدعاء
root.unmount
، لا يمكنك استدعاءroot.render
مرة أخرى على نفس الجذر. ستؤدي محاولة استدعاءroot.render
على جذر غير مثبتة إلى إطلاق خطأ"Cannot update an unmounted root"
. ومع ذلك، يمكنك إنشاء جذر جديد لنفس عنصر DOM بعد إلغاء تثبيت الجذر السابقة لذلك العنصر.
الاستخدام
عرض التطبيق المُبني بالكامل بواسطة React
إذا كان تطبيقك مبنيًا بالكامل بواسطة React، قم بإنشاء جذر واحدة لتطبيقك بالكامل.
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
عادةً ما يكون عليك تنفيذ هذا الشيء مرة واحدة فقط عند بدء التشغيل.
سيقوم بما يلي:
- العثور على عنصر DOM للمتصفح المعرف في ملف HTML الخاص بك.
- عرض مكون React لتطبيقك بداخله.
import { createRoot } from 'react-dom/client'; import App from './App.js'; import './styles.css'; const root = createRoot(document.getElementById('root')); root.render(<App />);
إذا كان تطبيقك مبنيًا بالكامل بواسطة React، فغالبًا لن تحتاج إلى إنشاء مزيد من الجذور أو استدعاء root.render
مرة أخرى.
من هذه النقطة وما بعدها، سيتولى React إدارة DOM للتطبيق بأكمله. لإضافة مكونات إضافية، احتضنها داخل المكون App
. عندما تحتاج إلى تحديث واجهة المستخدم، يمكن أن تقوم كل من مكوناتك بذلك عن طريق استخدام الحالة. وعندما تحتاج إلى عرض محتوى إضافي مثل نافذة منبثقة أو نصائح خارج عنصر DOM، اعرضه باستخدام createPortal
.
عرض صفحة مبنية جزئيًا بواسطة React
إذا كانت صفحتك ليست مبنية بالكامل باستخدام React، يمكنك استدعاء createRoot
عدة مرات لإنشاء جذر لكل قسم من أقسام واجهة المستخدم الرئيسية التي تُدار بواسطة React. يمكنك عرض محتوى مختلف في كل جذر عن طريق استدعاء root.render
.
في هذا المثال، يتم عرض نوعين مختلفين من مُكوِّنات React في عنصري DOM موجودين في ملف index.html
:
import './styles.css'; import { createRoot } from 'react-dom/client'; import { Comments, Navigation } from './Components.js'; const navDomNode = document.getElementById('navigation'); const navRoot = createRoot(navDomNode); navRoot.render(<Navigation />); const commentDomNode = document.getElementById('comments'); const commentRoot = createRoot(commentDomNode); commentRoot.render(<Comments />);
يمكنك أيضًا إنشاء عنصر DOM جديد باستخدام document.createElement()
وإضافتها يدويًا إلى المستند.
const domNode = document.createElement('div');
const root = createRoot(domNode);
root.render(<Comment />);
document.body.appendChild(domNode); // يمكنك إضافتها في أي مكان بالمستند
لإزالة شجرة React من عنصر DOM وتنظيف جميع الموارد المستخدمة من قِبلها، استدعِ root.unmount
.
root.unmount();
تعتبر هذه الطريقة مفيدة بشكل رئيسي إذا كانت مُكوِّنات React الخاصة بك داخل تطبيق مكتوب بإطار عمل مختلف.
تحديث المكون الجذر
يمكنك استدعاء render
أكثر من مرة على نفس الجذر. طالما أن هيكل شجرة المُكوِّن يُطابق ما تم عرضه سابقًا، ستُحافظ React على الحالة. لاحظ كيف يمكنك كتابة نص في المُدخل، مما يعني أن التحديثات الناتجة عن استدعاءات render
المتكررة كل ثانية في هذا المثال لا تُؤدي إلى حذف البيانات:
import { createRoot } from 'react-dom/client'; import './styles.css'; import App from './App.js'; const root = createRoot(document.getElementById('root')); let i = 0; setInterval(() => { root.render(<App counter={i} />); i++; }, 1000);
من غير الشائع أن تستدعي render
عدة مرات. عادةً، يمكن لمكوناتك تحديث الحالة بدلاً من ذلك.
حل المشكلات
لقد أنشأت جذرًا، ولكن لا يتم عرض أي شيء
تأكد من أنك لم تنسى أن تقوم بـ عرض تطبيقك فعليًا في الجذر:
import { createRoot } from 'react-dom/client';
import App from './App.js';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
إلى أن تفعل ذلك، لن يتم عرض أي شيء.
أواجه خطأ: "Target container is not a DOM element"
هذا الخطأ يعني أن ما تقوم بتمريره إلى createRoot
ليس عنصر DOM.
إذا لم تكن متأكدًا مما يحدث، جرب استخدام console.log
للتحقق من القيمة التي تمررها إلى createRoot
:
const domNode = document.getElementById('root');
console.log(domNode); // ???
const root = createRoot(domNode);
root.render(<App />);
على سبيل المثال، إذا كانت domNode
تساوي null
، فهذا يعني أن getElementById
قد أرجع null
. وهذا سيحدث إذا لم يكن هناك عنصر في المستند يحمل المعرف ID المعطاة في وقت استدعائك للدالة. قد تكون هناك بعض الأسباب وراء ذلك:
- ربما يكون المعرف الذي تبحث عنه مختلف عن المعرف التي استخدمته في ملف HTML. تحقق من الأخطاء الإملائية!
- ربما لا يمكن لعنصر
<script>
الخاص بك “رؤية” أي عنصر DOM تظهر بعده في HTML.
طريقة شائعة أخرى للحصول على هذا الخطأ هي كتابة createRoot(<App />)
بدلاً من createRoot(domNode)
.
أواجه خطأ: "Functions are not valid as a React child."
هذا الخطأ يعني أن ما تمرره إلى root.render
ليس مكوِّن React.
قد يحدث هذا إذا قمت باستدعاء root.render
باستخدام Component
بدلاً من <Component />
:
// 🚩 خاطئ: App هي دالة، وليست مكوِّن.
root.render(App);
// ✅ صحيح: <App /> هو مكوِّن.
root.render(<App />);
أو إذا قمت بتمرير دالة إلى root.render
بدلاً من نتيجة استدعائها:
// 🚩 خاطئ: createApp هي دالة، وليست مكوِّن.
root.render(createApp);
// ✅ صحيح: قم باستدعاء createApp لترجع مكوِّنًا.
root.render(createApp());
يتم إعادة إنشاء HTML المنشأة بواسطة الخادم من جديد
إذا كان تطبيقك قد تم رسمه بواسطة الخادم ويتضمن HTML الأولي الذي تم إنشاؤه بواسطة React، قد تلاحظ أن إنشاء جذر واستدعاء root.render
يحذف كل هذا الHTML، ثم يُعيد إنشاء جميع عناصر DOM من جديد. قد يكون هذا أبطأ، ويؤدي إلى إعادة تعيين التركيز ومواقع التمرير، وقد يؤدي إلى فقدان مدخلات المستخدم الأخرى.
يجب على تطبيقات التي تم رسمها بواسطة الخادم استخدام hydrateRoot
بدلاً من createRoot
:
import { hydrateRoot } from 'react-dom/client';
import App from './App.js';
hydrateRoot(
document.getElementById('root'),
<App />
);
لاحظ أن واجهة برمجة التطبيقات API مختلفة. عادةً ما لن يكون هناك مزيد من استدعاءات root.render
.