আগের পর্বে আমরা React পরিচিতি আর Vite দিয়ে প্রজেক্ট সেটআপ শিখেছিলাম। এই পর্বে আমরা দেখব JSX — React কোডে HTML-এর মতো দেখতে যে সিনট্যাক্স ব্যবহার হয়, সেটা আসলে কী, আর কীভাবে কাজ করে।
JSX কী?
JSX (JavaScript XML) হলো JavaScript-এর একটা সিনট্যাক্স এক্সটেনশন, যেটা দিয়ে JavaScript কোডের ভেতরেই HTML-এর মতো লেখা যায়। এটা কোনো আলাদা ভাষা না — এটা "সিনট্যাক্টিক সুগার", মানে লেখার একটা সহজ উপায়, যেটা পেছনে গিয়ে সাধারণ JavaScript ফাংশন কলে রূপান্তরিত হয়।
// JSX দিয়ে লেখা
const element = <h1>হ্যালো, আরিফ!</h1>;
// এটা আসলে পেছনে এভাবে রূপান্তরিত হয় (React.createElement কল)
const element = React.createElement("h1", null, "হ্যালো, আরিফ!");
দুটোই একই জিনিস তৈরি করে — শুধু JSX লেখাটা অনেক বেশি পড়া আর বোঝা সহজ, ঠিক HTML-এর মতো দেখতে। এই রূপান্তরের কাজটা করে Babel, যা Vite প্রজেক্টে বিল্ড টাইমে স্বয়ংক্রিয়ভাবে চলে।
JSX আর HTML-এর পার্থক্য
দেখতে প্রায় একই রকম হলেও কিছু গুরুত্বপূর্ণ পার্থক্য আছে:
| বৈশিষ্ট্য | HTML | JSX |
|---|---|---|
| ক্লাস দেওয়া | class="box" |
className="box" |
| লেবেল-ইনপুট যুক্ত করা | for="email" |
htmlFor="email" |
| সেলফ-ক্লোজিং ট্যাগ | <img> (ঐচ্ছিক ক্লোজ) |
<img /> (বাধ্যতামূলক ক্লোজ) |
| অ্যাট্রিবিউট নাম | onclick |
onClick (camelCase) |
| মূল এলিমেন্ট | একাধিক টপ-লেভেল ট্যাগ চলে | একটাই মূল ট্যাগ থাকতে হবে |
কেন className, class না? কারণ class JavaScript-এর একটা রিজার্ভড কীওয়ার্ড (ক্লাস বানানোর জন্য ব্যবহার হয়, যেমন Advanced JS সিরিজে শিখেছিলাম) — JSX আসলে JavaScript-এই রূপান্তরিত হয়, তাই সংঘর্ষ এড়াতে className ব্যবহার করা হয়।
একটা মূল এলিমেন্ট বাধ্যতামূলক কেন?
JSX-এ পাশাপাশি একাধিক টপ-লেভেল এলিমেন্ট রাখা যায় না — সবকিছু একটা প্যারেন্টের ভেতরে থাকতে হবে।
// ❌ এরর — দুটো টপ-লেভেল এলিমেন্ট
function App() {
return (
<h1>শিরোনাম</h1>
<p>প্যারাগ্রাফ</p>
);
}
// ✅ ঠিক আছে — একটা <div>-এর ভেতরে সব
function App() {
return (
<div>
<h1>শিরোনাম</h1>
<p>প্যারাগ্রাফ</p>
</div>
);
}
যদি অতিরিক্ত একটা <div> DOM-এ যোগ করতে না চাও, React Fragment দেয় — এটা DOM-এ কোনো এলিমেন্ট তৈরি করে না, শুধু JSX-এর নিয়ম মানার জন্য একটা "অদৃশ্য" wrapper।
function App() {
return (
<>
<h1>শিরোনাম</h1>
<p>প্যারাগ্রাফ</p>
</>
);
}
// <>...</> হলো <React.Fragment>...</React.Fragment>-এর শর্টহ্যান্ড
JSX-এ JavaScript এক্সপ্রেশন বসানো — কার্লি ব্রেস
JSX-এর সবচেয়ে শক্তিশালী ফিচার হলো { } দিয়ে HTML-এর ভেতরেই সরাসরি JavaScript এক্সপ্রেশন বসিয়ে দেওয়া যায়।
const name = "আরিফ";
const age = 28;
function App() {
return (
<div>
<h1>আমার নাম {name}</h1>
<p>আগামী বছর আমার বয়স হবে {age + 1}</p>
<p>নাম বড় হাতের অক্ষরে: {name.toUpperCase()}</p>
</div>
);
}
{ }-এর ভেতরে যেকোনো বৈধ JavaScript এক্সপ্রেশন বসানো যায় — ভ্যারিয়েবল, গণনা, ফাংশন কল, টার্নারি — শুধু if-এর মতো স্টেটমেন্ট সরাসরি বসানো যায় না (এটা পরে Conditional Rendering পর্বে দেখব)।
Attribute-এও JavaScript এক্সপ্রেশন
শুধু টেক্সট কন্টেন্টেই না, HTML অ্যাট্রিবিউটেও { } দিয়ে ডাইনামিক মান বসানো যায়:
const imageUrl = "https://example.com/photo.jpg";
const isActive = true;
function App() {
return (
<div>
<img alt="প্রোফাইল ছবি" src={imageUrl} />
<button className={isActive ? "btn-active" : "btn-inactive"}>
বাটন
</button>
</div>
);
}
Inline Style — অবজেক্ট হিসেবে
JSX-এ style অ্যাট্রিবিউট একটা স্ট্রিং না, বরং একটা JavaScript অবজেক্ট নেয় — সিএসএস প্রপার্টি camelCase-এ লিখতে হয়।
function App() {
const boxStyle = {
backgroundColor: "#2563eb", // background-color না, camelCase
padding: "16px",
borderRadius: "8px", // border-radius না
color: "white"
};
return <div style={boxStyle}>স্টাইল করা বক্স</div>;
// অথবা সরাসরি ইনলাইনে (দুই কার্লি ব্রেস — একটা JSX এক্সপ্রেশনের, একটা অবজেক্টের)
// <div style={{ backgroundColor: "#2563eb", padding: "16px" }}>...</div>
}
লাইভ ডেমো — JSX-এ ডাইনামিক ডেটা
নিচের বাটনে চাপো — একটা React কম্পোনেন্ট, যেখানে JSX-এর ভেতরে JavaScript এক্সপ্রেশন (স্ট্রিং, গণনা, শর্তসাপেক্ষ স্টাইল) সরাসরি ব্যবহার হচ্ছে।
লক্ষ্য করো — {'{'}temp{'}'}°C, {'{'}isHot ? ... : ...{'}'} — সবই JSX-এর ভেতরে সরাসরি JavaScript এক্সপ্রেশন।
কমেন্ট লেখা JSX-এ
JSX-এর ভেতরে সাধারণ // বা <!-- --> কমেন্ট কাজ করে না — কার্লি ব্রেসের ভেতরে JavaScript কমেন্ট সিনট্যাক্স ব্যবহার করতে হয়।
function App() {
return (
<div>
{/* এটা একটা সঠিক JSX কমেন্ট */}
<h1>শিরোনাম</h1>
{"❌ এটা কমেন্ট না — এটা আসলে JSX-এ একটা টেক্সট হিসেবে দেখাবে"}
</div>
);
}
একটা সম্পূর্ণ উদাহরণ — প্রোফাইল কার্ড
চলো এই পর্বের সবকিছু মিলিয়ে একটা প্রোফাইল কার্ড কম্পোনেন্ট বানাই।
// src/App.jsx
function App() {
const user = {
name: "আরিফ",
role: "ওয়েব ডেভেলপার",
isOnline: true,
projectCount: 5
};
const cardStyle = {
background: "white",
padding: "20px",
borderRadius: "10px",
boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
maxWidth: "300px"
};
const statusStyle = {
color: user.isOnline ? "#16a34a" : "#9ca3af",
fontSize: "13px"
};
return (
<div style={cardStyle}>
<h2>{user.name}</h2>
<p>{user.role}</p>
<p style={statusStyle}>
{user.isOnline ? "🟢 অনলাইন" : "⚪ অফলাইন"}
</p>
<p>মোট প্রজেক্ট: {user.projectCount}</p>
</div>
);
}
export default App;
এখানে একটা মাত্র <div> রুট এলিমেন্ট, অবজেক্ট প্রপার্টি অ্যাক্সেস (user.name), টার্নারি এক্সপ্রেশন (isOnline ? ... : ...), আর অবজেক্ট-ভিত্তিক স্টাইল — সবকিছু এই পর্বে শেখা বিষয়ের সমাহার।
নিজে চেষ্টা করো
Exercise:
- আগের পর্বে বানানো Vite প্রজেক্টে
App.jsxখুলে নিজের নাম, বয়স, প্রিয় ভাষা দিয়ে একটা ছোট প্রোফাইল দেখাও। - উপরের প্রোফাইল কার্ডে একটা
skillsঅ্যারে যোগ করো,.join(", ")দিয়ে JSX-এ দেখাও। - একটা এলিমেন্ট বানাও যার
classNameশর্তসাপেক্ষে (টার্নারি দিয়ে) পাল্টায় — একটা বুলিয়ান ভ্যারিয়েবলের উপর ভিত্তি করে। - Fragment (
<>...</>) ব্যবহার করে একটা কম্পোনেন্ট বানাও যেখানে কোনো অতিরিক্ত<div>DOM-এ যোগ হচ্ছে না।
পরের পর্বে যা থাকছে
পরের পর্বে আমরা শিখব Component পরিচিতি — Functional Component কী, কীভাবে একাধিক ছোট ছোট কম্পোনেন্ট মিলিয়ে একটা বড় UI বানানো যায়।