কনটেক্সট দিয়ে ডেটা গভীরভাবে পাঠানো (Passing Data Deeply with Context)
Context lets the parent component make some information available to any component in the tree below it—no matter how deep—without passing it explicitly through props.
React-এ আমরা সাধারণভাবে ডেটা প্যারেন্ট কম্পোনেন্ট থেকে চাইল্ড কম্পোনেন্টে props দিয়ে পাঠাই। কিন্তু যখন এই ডেটা অনেক লেভেল নিচের কোনো কম্পোনেন্টে দরকার হয়, তখন মাঝখানের সব কম্পোনেন্টকে props নিতে হয়—even যদি তারা সেই ডেটা ব্যবহার না করে। এই জিনিসটা এক সময়ে বিরক্তিকর এবং কোড ঝামেলাপূর্ণ হয়ে ওঠে।
React-এর Context API এই সমস্যার সমাধান করে। কনটেক্সটের মাধ্যমে আপনি যেকোনো ডেটা গ্লোবালি শেয়ার করতে পারেন এমনভাবে, যেন সেটা আপনার কম্পোনেন্ট ট্রির যেকোনো গভীর লেভেলের কম্পোনেন্ট সরাসরি access করতে পারে—props দিয়ে না পাঠিয়েও।
এই টপিক থেকে আপনি যা শিখবেন:
- Prop drilling কী এবং কেন এটা সমস্যা
- কীভাবে কনটেক্সট দিয়ে রিপিটিটিভ prop পাসিং বাদ দিতে পারবেন
- কনটেক্সট কখন ব্যবহার করবেন
- Context-এর কিছু জনপ্রিয় বিকল্প
Props পাস করার সমস্যা
React-এর props ব্যবস্থাটা অনেক পরিষ্কার—এক কম্পোনেন্ট থেকে আরেকটিতে নির্দিষ্ট ডেটা পাঠানো যায়। তবে সমস্যা হয় যখন সেই ডেটা অনেক নিচের কম্পোনেন্টে দরকার হয়। তখন আপনাকে props গুলো একাধিক লেভেল ধরে ধরে নিচে পাঠাতে হয়—even যদি মাঝখানের কম্পোনেন্টগুলো সেটা ব্যবহার না করে। এই জিনিসটাই prop drilling নামে পরিচিত।
স্টেট উপরে তোলা (Lifting State Up)
ধরুন আপনি এমন একটা স্টেট উপরে রেখেছেন, যেটা দুইটা চাইল্ড কম্পোনেন্টে দরকার। তখন আপনি সেই স্টেটটা প্যারেন্টে রাখতে বাধ্য হবেন এবং দুইটা চাইল্ডে props দিয়ে পাঠাতে হবে। এটা ছোট স্কেলে ঠিক আছে, কিন্তু যখন কম্পোনেন্ট ট্রি বড় হয়, তখন এটা manage করা কষ্টকর হয়ে পড়ে।
Prop drilling উদাহরণ
ধরুন ১০টা কম্পোনেন্ট নিয়ে একটা ট্রি আছে। ডেটা রুট কম্পোনেন্টে আছে, আর দরকার নিচের ৭-৮ নাম্বার কম্পোনেন্টে। তখন সেই ডেটা এক লেভেল করে করে props হিসেবে নিচে পাঠাতে হবে। মাঝখানের অনেকগুলো কম্পোনেন্ট শুধুমাত্র ওই ডেটার “carrier” হিসেবে কাজ করবে—তারা নিজেরা ডেটা ইউজও করবে না। এটাই হচ্ছে prop drilling।
Absolutely! Here's the 2nd part translated for you as a React Developer, in simple and clean language:
এখন যা হচ্ছে
এই কোডে আমরা প্রতিটা <Heading>
-এ আলাদা করে level
প্রপ্স দিচ্ছি, যেমন:
<Section>
<Heading level={3}>About</Heading>
<Heading level={3}>Photos</Heading>
<Heading level={3}>Videos</Heading>
</Section>
এটা ঠিকঠাক কাজ করে, কিন্তু যদি আমরা একটা সেকশনের ভেতরের সব হেডিং একই level
এ রাখতে চাই, তাহলে বারবার level
লিখতে হয়। একটু ঝামেলার মনে হয়, না?
এখন যা করতে চাই
আমরা চাই যেন <Section>
-এ একবার level
দিলে, সেই লেভেল নিচের সব <Heading>
-এ অটো চলে যায়। যেমন:
<Section level={3}>
<Heading>About</Heading>
<Heading>Photos</Heading>
<Heading>Videos</Heading>
</Section>
এটা হলে কোড আরও পরিষ্কার হবে এবং ম্যানেজ করা সহজ হবে।
সমস্যা কী?
এখন প্রশ্ন হলো, <Heading>
কিভাবে বুঝবে তার কাছের Section
কী level
দিয়েছে?
Prop দিয়ে তো পারব না, কারণ <Heading>
সরাসরি level
পাচ্ছে না আর। এই জায়গাতেই React context ব্যবহার করতে হবে।
সমাধান: React Context
আমরা এটা ৩ ধাপে করব:
- Context তৈরি করব – নাম দিব
LevelContext
(এই context ধরে রাখবে heading এর level) - Context ব্যবহার করব –
Heading
কম্পোনেন্ট context থেকেlevel
নিবে - Context Provide করব –
Section
কম্পোনেন্ট context দিয়ে নিচের সব কম্পোনেন্টকেlevel
দিবে
এইভাবে, একবার ওপর থেকে level
দিলেই নিচের সব হেডিং সেটি পেয়ে যাবে — চাইল্ড কম্পোনেন্ট সরাসরি props ছাড়া ডেটা পাবে।
Context Diagram বোঝায়
React context এমনভাবে কাজ করে, যেন কোনো parent কম্পোনেন্ট উপরে থেকে একটা value দিয়ে দেয়, আর ভেতরের যত child আছে — তারা চাইলে সেই value “access” করতে পারে।
🔸 এটা কাজ করে, চাইল্ড যদি খুব কাছাকাছি হয়,
🔸 আবার দূরে দূরে nested child হলেও কাজ করে।
এই পুরো উদাহরণটা খুব চমৎকারভাবে React-এর Context API শেখায়, আর তুমি যেভাবে "level" অনুযায়ী হেডিং সাজিয়েছো, সেটা ভীষণভাবে কাজে লাগে nested components এর ক্ষেত্রে।
সংক্ষেপে মূল তিনটি ধাপ হলো:
✅ Step 1: Context তৈরি করা
import { createContext } from "react";
export const LevelContext = createContext(1);
👉 এটা হলো একটি সাধারণ context যার default value 1
(মানে <h1>
)
✅ Step 2: Context ব্যবহার করা
import { useContext } from "react";
import { LevelContext } from "./LevelContext.js";
export default function Heading({ children }) {
const level = useContext(LevelContext);
// switch করে level অনুযায়ী h1, h2... render করবে
}
👉 এখন আর <Heading level={2}>
দিতে হচ্ছে না, কারণ level
context থেকে আসবে।
✅ Step 3: Context প্রদান করা
import { LevelContext } from "./LevelContext.js";
export default function Section({ level, children }) {
return (
<section className="section">
<LevelContext.Provider value={level}>{children}</LevelContext.Provider>
</section>
);
}
👉 এখানে Section
নিজের children-দের level
context দিয়ে দিচ্ছে।
📌 সুবিধা:
- প্রতিবার
<Heading level={...}>
না লিখে, শুধুSection
এ level দিলেই চলে। - একেবারে clean এবং scalable component structure পাওয়া যায়।
তুমি কি চাও এই context-based heading system আরেকটু extend করে কিছু add করি? যেমন: auto-incremented level, dark mode context, বা nested list support?