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 هذا.- Canary only optional
onCaughtError: Callback called when React catches an error in an Error Boundary. Called with theerrorcaught by the Error Boundary, and anerrorInfoobject containing thecomponentStack. - Canary only optional
onUncaughtError: Callback called when an error is thrown and not caught by an Error Boundary. Called with theerrorthat was thrown, and anerrorInfoobject containing thecomponentStack. - optional
onRecoverableError: Callback called when React automatically recovers from errors. Called with anerrorReact throws, and anerrorInfoobject containing thecomponentStack. Some recoverable errors may include the original error cause aserror.cause. - optional
identifierPrefix: A string prefix React uses for IDs generated byuseId. Useful to avoid conflicts when using multiple roots on the same page.
- Canary only optional
العائدات
يعيد 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 عدة مرات. عادةً، يمكن لمكوناتك تحديث الحالة بدلاً من ذلك.
Show a dialog for uncaught errors
By default, React will log all uncaught errors to the console. To implement your own error reporting, you can provide the optional onUncaughtError root option:
import { createRoot } from 'react-dom/client';
const root = createRoot(
document.getElementById('root'),
{
onUncaughtError: (error, errorInfo) => {
console.error(
'Uncaught error',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);The onUncaughtError option is a function called with two arguments:
- The error that was thrown.
- An errorInfo object that contains the componentStack of the error.
You can use the onUncaughtError root option to display error dialogs:
import { createRoot } from "react-dom/client"; import App from "./App.js"; import {reportUncaughtError} from "./reportError"; import "./styles.css"; const container = document.getElementById("root"); const root = createRoot(container, { onUncaughtError: (error, errorInfo) => { if (error.message !== 'Known error') { reportUncaughtError({ error, componentStack: errorInfo.componentStack }); } } }); root.render(<App />);
Displaying Error Boundary errors
By default, React will log all errors caught by an Error Boundary to console.error. To override this behavior, you can provide the optional onCaughtError root option to handle errors caught by an Error Boundary:
import { createRoot } from 'react-dom/client';
const root = createRoot(
document.getElementById('root'),
{
onCaughtError: (error, errorInfo) => {
console.error(
'Caught error',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);The onCaughtError option is a function called with two arguments:
- The error that was caught by the boundary.
- An errorInfo object that contains the componentStack of the error.
You can use the onCaughtError root option to display error dialogs or filter known errors from logging:
import { createRoot } from "react-dom/client"; import App from "./App.js"; import {reportCaughtError} from "./reportError"; import "./styles.css"; const container = document.getElementById("root"); const root = createRoot(container, { onCaughtError: (error, errorInfo) => { if (error.message !== 'Known error') { reportCaughtError({ error, componentStack: errorInfo.componentStack, }); } } }); root.render(<App />);
Displaying a dialog for recoverable errors
React may automatically render a component a second time to attempt to recover from an error thrown in render. If successful, React will log a recoverable error to the console to notify the developer. To override this behavior, you can provide the optional onRecoverableError root option:
import { createRoot } from 'react-dom/client';
const root = createRoot(
document.getElementById('root'),
{
onRecoverableError: (error, errorInfo) => {
console.error(
'Recoverable error',
error,
error.cause,
errorInfo.componentStack,
);
}
}
);
root.render(<App />);The onRecoverableError option is a function called with two arguments:
- The error that React throws. Some errors may include the original cause as error.cause.
- An errorInfo object that contains the componentStack of the error.
You can use the onRecoverableError root option to display error dialogs:
import { createRoot } from "react-dom/client"; import App from "./App.js"; import {reportRecoverableError} from "./reportError"; import "./styles.css"; const container = document.getElementById("root"); const root = createRoot(container, { onRecoverableError: (error, errorInfo) => { reportRecoverableError({ error, cause: error.cause, componentStack: errorInfo.componentStack, }); } }); root.render(<App />);
حل المشكلات
لقد أنشأت جذرًا، ولكن لا يتم عرض أي شيء
تأكد من أنك لم تنسى أن تقوم بـ عرض تطبيقك فعليًا في الجذر:
import { createRoot } from 'react-dom/client';
import App from './App.js';
const root = createRoot(document.getElementById('root'));
root.render(<App />);إلى أن تفعل ذلك، لن يتم عرض أي شيء.
أواجه خطأ: “You passed a second argument to root.render”
من الأخطاء الشائعة تمرير خيارات createRoot إلى root.render(...):
To fix, pass the root options to createRoot(...), not root.render(...):
// 🚩 Wrong: root.render only takes one argument.
root.render(App, {onUncaughtError});
// ✅ Correct: pass options to createRoot.
const root = createRoot(container, {onUncaughtError});
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.