createRoot
একটি ব্রাউজার DOM নোডে React কম্পোনেন্ট দেখানোর জন্য createRoot আপনাকে একটি root তৈরী করতে দেবে।
const root = createRoot(domNode, options?)রেফারেন্স
createRoot(domNode, options?)
একটি ব্রাউজার DOM এলিমেন্টে React কম্পোনেন্ট দেখানোর স্বার্থে একটি React root তৈরী করার জন্য createRoot কল করুন।
import { createRoot } from 'react-dom/client';
const domNode = document.getElementById('root');
const root = createRoot(domNode);React domNode এর জন্য একটি root তৈরী করবে, এবং এর মধ্যকার DOM পরিচালনার দায়িত্ব নিয়ে নিবে। root তৈরী করবার পর আপনাকে এর মধ্যে একটি React কম্পোনেন্ট দেখাবার জন্য root.render কল করতে হবেঃ
root.render(<App />);সম্পূর্ণরূপে React দিয়ে বানানো একটি অ্যাপে সাধারণত একটি মাত্র createRoot কল থাকবে এর root কম্পোনেন্টের জন্য। যেই পেইজের বিভিন্ন অংশের জন্য React এর “ছিটেফোটা” ব্যবহৃত হয় সেগুলোতে যত গুলো ইচ্ছে আলাদা আলাদা root থাকতে পারে।
প্যারামিটার
-
domNode: একটা DOM এলিমেন্ট। React এই DOM এলিমেন্টের জন্য একটি root তৈরী করবে এবং root এ আপনাকে ফাংশন কল করতে দেবে, যেমন হতে পারে রেন্ডার হওয়া React কম্পোনেন্ট দেখানোর জন্য ফাংশনrender। -
optional
options: এই React root এর জন্য বিভিন্ন option সংবলিত একটি অবজেক্ট।- optional
onRecoverableError: যখন React স্বয়ংক্রিয় ভাবে কোন error থেকে নিজেকে recover করে তখন হওয়া কলব্যাক। - optional
identifierPrefix:useIdদিয়ে তৈরী হওয়া ID গুলোর জন্য React যে string prefix ব্যবহার করে। একই পেইজে যখন একাধিক rot থাকে তখন conflict এড়াতে এটা কাজে লাগে।
- optional
রিটার্ন
createRoot দুটি মেথডসহ একটি অব্জেক্ট রিটার্ন করেঃ render এবং unmount.
যেসব বিষয়ে সতর্ক থাকতে হবে
- আপনার অ্যাপ যদি সার্ভার থেকে রেন্ডার হয়,
createRoot()কাজ করবে না। বরংhydrateRoot()ব্যব্যহার করুন। - খুব সম্ভবত আপনার অ্যাপে একটি মাত্র
createRootকল থাকবে। আপনি যদি একটি ফ্রেমওয়ার্ক ব্যবহার করেন, সম্ভবতঃ সে-ই আপনার হয়ে কলটি করে দিবে। - যখন আপনি DOM ট্রি-এর অন্য একটি অংশে যা আপনার কম্পোনেন্টের চাইল্ড না(উদাহরণস্বরূপ একটা মোডাল বা টুলটিপ), JSX রেন্ডার করতে চাইবেন তখন
createRootএর বদলেcreatePortalব্যবহার করুন।
root.render(reactNode)
React root-এর ব্রাউজার DOM নোডে কোন JSX (“React node”) দেখানোর জন্য root.render কল করুন।
root.render(<App />);React root-এ <App /> দেখাবে, এবং এর মধ্যকার DOM পরিচালনার দায়িত্ব নিয়ে নিবে।
প্যারামিটার
reactNode: আপনি দেখাতে চান এমন একটি React নোড। এটা সাধারণত<App />এর মত এক টুকরো JSX হবে।, কিন্তু আপনিcreateElement()দিয়ে তৈরী করা একটি React এলিমেন্ট, একটি স্ট্রিং, একটি সংখ্যা,nullবাundefinedও পাস করতে পারেন।
রিটার্ন
root.render রিটার্ন করে undefined.
সতর্কতা
-
আপনি যখন প্রথম বারের মত
root.renderকল করবেন, React এর রুটের ভিতরে কম্পোনেন্ট রেন্ডার করবার আগে থাকা সব HTML কনটেন্ট মুছে ফেলবে। -
যদি আপনার রুটের DOM নোডে এমন HTML থাকে যা React সার্ভারে তৈরি করেছে বা বিল্ডের সময় তৈরি করেছে, তাহলে বরং
hydrateRoot()ব্যবহার করুন, যা বিদ্যমান HTML এ ইভেন্ট হ্যান্ডলারগুলো যুক্ত করে দেয়। -
আপনি যদি একি রুটে একাধিকবার
renderকল করেন, তাহলে আপনার পাঠানো সর্বশেষ JSX দেখানোর খাতিরে React প্রয়োজনমত DOM আপডেট করে ফেলবে। React আগেরবার রেন্ডার হওয়া ট্রি এর সাথে “মিলিয়ে দেখবে” এবং সিদ্ধান্ত নিবে DOM এর কোণ অংশগুলো পুনর্ব্যবহার করা যায় আর কোনগুলো আবার বানাতে হবে। একই রুটে আবারrenderকল করা রুট কম্পোনেন্টেsetfunction কল করার মতঃ React অপ্রয়োজনীয় DOM আপডেট এড়ানোর চেষ্টা করে।
root.unmount()
React রুটের মধ্যে রেন্ডার হওয়া একটি ট্রি মুছে ফেলতে root.unmount কল করুন।
root.unmount();সম্পূর্ণরূপে React দিয়ে বানানো অ্যাপের সাধারণত root.unmount এ কোন কল থাকে না।
এটা সে ক্ষেত্রে সবচেয়ে কাজে লাগে যদি অন্য কোন কোডের কারণে DOM থেকে আপনার React রুটের DOM নোড (বা ট্রিতে এর কোন পূর্বসূরী) মুছে যায়। উদাহরণস্বরূপ, ধরেন একটা jQuery ট্যাব প্যানেল আছে যা DOM থেকে অচল ট্যাবগুলোকে ফেলে দেয়। যদি একটা ট্যাব ফেলে দেওয়া হয়, তাহলে এই ট্যাবের মধ্যে থাকা যাবতীয় সব কিছু(ভিতরকার React রুটগুলো সহ) DOM থেকে মুছে যায়। সেক্ষেত্রে, root.unmount কল করার মাধ্যমে আপনার React কে বলতে হবে মুছে যাওয়া রুটের কনটেন্ট ম্যানেজ করা “বন্ধ” করতে। না হলে, মুছে যাওয়া রুটের ভেতরকার কম্পোনেন্ট সাবস্ক্রিপশনের মত global resource মুছবে না এবং সেগুলো ফ্রি হবে না।
root.unmount কল করলে রুটের সব কম্পোনেন্ট আনমাউন্ট হবে এবং রুট DOM নোড থেকে React “detach” হয়ে যাবে। একই সাথে ট্রিতে কোন ইভেন্ট হ্যান্ডলার বা স্টেট থাকলে সেটাও মুছে যাবে।
প্যারামিটার
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 />);সাধারণত, আপনাকে একবারই শুরুতে এই কোড রান করতে হবে। এটা যা করবে তা হলঃ
- আপনার HTML এ ডিফাইন্ড হওয়া ব্রাউজার DOM নোড খুঁজে বের করবে।
- আপনার অ্যাপের ভেতর থাকা 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 কম্পোনেন্টে তাদের nest করুন। যখন আপনার UI আপডেটের প্রয়োজন হবে, আপনার প্রতিটি কম্পোনেন্ট স্টেট ব্যবহার করে সেটা করতে পারবে। যখন আপনার DOM নোডের বাইরে অতিরিক্ত কোন কনটেন্ট যেমন একটা মোডাল বা টুলটিপ দেখানোর প্রয়োজন হবে তখন, একটা পোর্টাল ব্যবহার করে সেটা রেন্ডার করুন।
React দিয়ে আংশিকভাবে বানানো পেইজের রেন্ডারিং
যদি আপনার পেইজ সম্পূর্ণরূপে React দিয়ে বানানো না হয়ে থাকে, React দিয়ে পরিচালিত প্রতিটি উচ্চ স্তরের UI piece এর জন্য একটি রুট তৈরি করার খাতিরে আপনি একাধিকবার createRoot কল করতে পারেন। আপনি root.render কল করার মাধ্যমে প্রতিটি রুটে ভিন্ন ভিন্ন কনটেন্ট দেখাতে পারেন।
এখানে, দুটি ভিন্ন React কম্পোনেন্ট index.html এর দুটি DOM নোডে রেন্ডার হচ্ছেঃ
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 />);
আপনি document.createElement() ব্যবহার করে একটা নতুন DOM নোড তৈরীও করতে পারেন এবং একে নিজে নিজে ডকুমেন্টে যোগ করতে পারেন।
const domNode = document.createElement('div');
const root = createRoot(domNode);
root.render(<Comment />);
document.body.appendChild(domNode); // আপনি ডকুমেন্টের যেকোন জায়গায় এটা যোগ করতে পারেনDOM নোড থেকে React ট্রি সরাতে এবং এর ব্যবহৃত সকল রিসোর্স মুছে ফেলতে root.unmount কল করুন।
root.unmount();এইটা সাধারণত সবচেয়ে কাজে লাগে যদি অ্যাপের ভিতরে থাকা আপনার React কম্পোনেন্টগুলো ভিন্ন কোন ফ্রেমওয়ার্কে লেখা থাকে।
একটি রুট কম্পোনেন্ট আপডেট করা
আপনি একই রুটে একাধিকবার render কল করতে পারেন। যতক্ষণ পর্যন্ত আগে থেকে রেন্ডার হওয়া অবস্থার সাথে কম্পোনেন্ট ট্রি এর গঠনবিন্যাস মিলে যাচ্ছজে, React state সংরক্ষণ করবে। খেয়াল করুন যে আপনি ইনপুটে টাইপ করতে পারছেন, যার অর্থ প্রতি সেকেন্ডে পুনারবৃত্ত হওয়া 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 একাধিকবার কল করা হয় না, বরং আপনার কম্পোনেট গুলোই state আপডেট করে।
ট্রাবলশ্যুট
একটা রুট তৈরী করবার পরও কিছুই দেখাচ্ছে না
নিশ্চিত করুন যে আপনি আসলেই রুটে আপনার অ্যাপ রেন্ডার করতে ভুলে যাননি।
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 নোড না।
আপনি যদি নিশ্চিত না হন যে কি হচ্ছে, একে logging করার চেষ্টা করুনঃ
const domNode = document.getElementById('root');
console.log(domNode); // ???
const root = createRoot(domNode);
root.render(<App />);উদাহরণস্বরূপ, যদি domNode null হয়, এর অর্থ getElementByIdnull রিটার্ন করেছে। এটা হবে যদি আপনার কল করার সময়ে ডকুমেন্টে ওই ID এর কোন নোড না থাকে। এর কিছু কারণ হতে পারে এমনঃ
- হতে পারে আপনি যেই ID খুজছেন সেটা আপনার HTML এ ব্যবহার করা ID থেকে আলাদা। টাইপিং এ ভুল হয়েছে কি না নিশ্চিত হন!
- হয়ত আপনার বান্ডলের
<script>ট্যাগ HTML-এ এর পরে কোন DOM নোড “দেখতে” পারছে না।
এই এরর পাবার আরেকটি কমন কারণ হল createRoot(domNode) এর বদলে createRoot(<App />) লেখা।
একটা এরর দেখাচ্ছেঃ “Functions are not valid as a React child.”
এই এররের অর্থ হল, আপনি যা root.render এ পাঠাচ্ছেন তা React কম্পোনেন্ট নয়।
এটা হতে পারে যদি আপনি root.render কে <Component /> এর বদলে Component দিয়ে কল করেনঃ
// 🚩 ভুলঃ অ্যাপ একটা ফাংশন, কম্পোনেন্ট না।
root.render(App);
// ✅ সঠিকঃ: <App /> একটা কম্পোনেন্ট।
root.render(<App />);অথবা যদি আপনি root.render এ একটা ফাংশন পাঠিয়ে থাকেন, যেখানে আসলে এই ফাংশন কলের ফলাফল পাঠাবার কথাঃ
// 🚩 ভুলঃ createApp একটা ফাংশন, কম্পোনেন্ট না।
root.render(createApp);
// ✅ সঠিকঃ একটা কম্পোনেন্ট রিটার্ন করার জন্য createApp কল করুন।
root.render(createApp());সার্ভার থেকে রেন্ডার হওয়া HTML একদম শুরু থেকে তৈরী হচ্ছে
যদি আপনার অ্যাপ সার্ভার থেকে রেন্ডার হয়ে থাকে এবং React এর তৈরী করা ইনিশিয়াল HTML থাকে ওতে, আপনি খেয়াল করবেন যে root.render কল করলে সব HTML মুছে যায়, এবং একদম শুরু থেকে সব DOM নোড তৈরী হয়। এটা ধীরতর হতে পারে, ফোকাস এবং স্ক্রল পজিশন রিসেট হয়ে যায়, এবং ব্যবহারকারীর ইনপুটও হারিয়ে যেতে পারে।
সার্ভার থেকে রেন্ডার হওয়া অ্যাপের ক্ষেত্রে অবশ্যই createRoot এর বদলে hydrateRoot এর ব্যবহার করতে হবেঃ
import { hydrateRoot } from 'react-dom/client';
import App from './App.js';
hydrateRoot(
document.getElementById('root'),
<App />
);খেয়াল করুন এর API আলাদা। বিশেষ করে, আর কোন root.render কল হবে না।