UI এর বর্ণনা

React একটা জাভাস্ক্রিপ্ট লাইব্রেরি যার কাজ user interfaces (UI) রেন্ডার করা। UI বিভিন্ন ক্ষুদ্র একক যেমন বাটন, টেক্সট বা ছবির মাধ্যমে গড়ে ওঠে। React আপনাকে সুযোগ দেয় সেগুলোকে reusable, nestable কম্পোনেন্টে একত্রিত করার। ওয়েবসাইট হোক বা ফোনের অ্যাপ, যা কিছু আপনি স্ক্রিনে দেখতে পান, সব কিছুই কম্পোনেন্টে ভেঙে ফেলা সম্ভব। এই অধ্যায়ে, আপনি React কম্পোনেন্ট বানানো, পরিবর্তন করা এবং লজিকের উপর ভিত্তি করে প্রদর্শন করা শিখবেন।

আপনার প্রথম কম্পোনেন্ট

React অ্যাপ্লিকেশনগুলো UI এর পৃথক পৃথক কিছু অংশের মাধ্যমে গড়ে ওঠে যাদের নাম কম্পোনেন্ট। একটা React কম্পোনেন্ট হচ্ছে একটা জাভাস্ক্রিপ্ট ফাংশন যা আপনি মার্কাপ দিয়ে সুন্দর করে তুলতে পারেন। একটা কম্পোনেন্ট একটা বাটনের মত ছোট বা একটা পেইজের মত বড় হতে পারে। এখানে দেখতে পাচ্ছেন একটা একটা Gallery যা তিনটি Profile কম্পোনেন্ট রেন্ডার করছেঃ

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

এই বিষয়ে শিখতে প্রস্তুত তো?

কীভাবে React কম্পোনেন্ট ডিক্লেয়ার এবং ব্যবহার করবেন তা জানতে পড়ুন আপনার প্রথম কম্পোনেন্ট।

আরো পড়ুন

কম্পোনেন্টের ইমপোর্ট এবং এক্সপোর্ট

আপনি একটা ফাইলে অনেকগুলো কম্পোনেন্ট ডিক্লেয়ার করতে পারেন, তবে বড় বড় ফাইল navigate করাটা বেশ কষ্টসাধ্য হতে পারে। এটা সমাধানের জন্য, আপনি একটা কম্পোনেন্টকে তার নিজের ফাইলে এক্সপোর্ট করতে পারেন, এবং পরে সেটাকে অন্য ফাইলে ইমপোর্ট করতে পারেন।

import Profile from './Profile.js';

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

এই বিষয়ে শিখতে প্রস্তুত তো?

কীভাবে কম্পোনেন্টকে তার নিজের একাধিক ফাইলে ভাগ করে নিবেন জানতে পড়ুন কম্পোনেন্টের ইমপোর্ট এবং এক্সপোর্ট।

আরো পড়ুন

JSX দিয়া মার্ক আপ লেখা

প্রতিটা React কম্পোনেন্ট একেকটা জাভাস্ক্রিপ্ট ফাংশন যেটাতে কিছু মার্কাপ থাকতে পারে যা React ব্রাউজারে রেন্ডার করে।এই মার্কাপ এর প্রতিনিধিত্ব করার জন্য React কম্পোনেন্টগুলো একটা সিনট্যাক্স এক্সটেনশন ব্যবহার করে যার নাম JSX। JSX অনেকটা HTML এর মত দেখতে, কিন্তু আরেকটু কঠোর যা dynamic তথ্য দেখাতে পারে।

আমরা যদি ইতোমধ্যে লেখা HTML মার্কাপ একটা React কম্পোনেন্টে পেস্ট করে দেই, এটা সব সময় কাজ করবে নাঃ

export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve spectrum technology
    </ul>

আপনার যদি এরকম আগে থেকে HTML লেখা থাকে, সেটা আপনি converter ব্যবহার করে ঠিক করতে পারেনঃ

export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://i.imgur.com/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve spectrum technology</li>
      </ul>
    </>
  );
}

এই বিষয়ে শিখতে প্রস্তুত তো?

কীভাবে সঠিকভাবে JSX লিখবেন জানার জন্য পড়ুন JSX দিয়ে মার্কাপ লেখা।

আরো পড়ুন

কার্লি ব্রেইস ব্যবহার করে JSX এর মধ্যে জাভাস্ক্রিপ্ট

JSX আপনাকে একটা জাভাস্ক্রিপ্ট ফাইলে HTML এর মত মার্কাপ লিখতে দেয়, এতে রেন্ডারিং লজিক আর কনটেন্ট একি জায়গায় থাকে। মাঝে মাঝে আপনি চাইবেন সেই মার্কাপের মধ্যে কিছু জাভাস্ক্রিপ্ট লজিক যুক্ত করতে বা ডাইনামিক প্রোপার্টি রেফারেন্স করতে। এরকম ক্ষেত্রে, আপনি আপনার JSX এর মধ্যে কার্লি ব্রেইস ব্যবহার করে জাভাস্ক্রিপ্টের জন্য “একটা জানালা খুলে দিতে পারেন”:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

এই বিষয়ে শিখতে প্রস্তুত তো?

JSX থেকে কীভাবে জাভাস্ক্রিপ্ট ডেটায় এক্সেস নিবেন জানতে, কার্লি ব্রেইস ব্যবহার করে JSX এর মধ্যে জাভাস্ক্রিপ্ট পড়ুন।

আরো পড়ুন

একটা কম্পোনেন্টে প্রপ পাঠানো

React কম্পোনেন্ট নিজেদের মধ্যে যোগাযোগ করতে প্রপ ব্যবহার করে। যেকোন প্যারেন্ট কম্পোনেন্ট তার চাইল্ড কম্পোনেন্টে তথ্য পাঠাতে পারে প্রপ দেবার মাধ্যমে। প্রপ হয়ত আপনাকে HTML এট্রিবিউটের কথা মনে করিয়ে দেবে, তবে আপনি এর মধ্য দিয়ে যেকোন জাভাস্ক্রিপ্ট ভ্যালু পাঠাতে পারেন। সেটা হতে পারে অবজেক্ট, অ্যারে, ফাংশন এমনকি JSX।

import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

এই বিষয়ে শিখতে প্রস্তুত তো?

কীভাবে প্রপ পাস এবং রিড করবেন জানতে পড়ুন একটা কম্পোনেন্টে প্রপ পাঠানো

আরো পড়ুন

কন্ডিশনাল রেন্ডারিং

বেশির ভাগ সময় ক্ষেত্র বিশেষে আপনার কম্পোনেন্টগুলোর প্রয়োজন হবে বিভিন্ন কিছু প্রদর্শন করা। React এ, জাভাস্ক্রিপ্ট সিনট্যাক্স যেমন if স্টেটমেন্ট, && এবং ? : অপারেটর ব্যবহার করে কন্ডিশনালি JSX রেন্ডার করতে পারেন।

এই উদাহরণে জাভাস্ক্রিপ্টের && অপারেটর ব্যবহৃত হয়েছে একটা চেকমার্ক কন্ডিশনালি রেন্ডার করার জন্যঃ

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✔'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}

এই বিষয়ে শিখতে প্রস্তুত তো?

কন্ডিশনালি কনটেন্ট প্রদর্শনের বিভিন্ন পন্থা জানতে পড়ুন Conditional Rendering

আরো পড়ুন

লিস্টের রেন্ডারিং

আপনি প্রায়ই চাইবেন একটা ডেটা কালেকশন থেকে একাধিক একই রকম কনটেন্ট প্রদর্শন করতে। আপনি আপনার ডেটার অ্যারে-কে একটা কম্পোনেন্টের অ্যারে-তে রূপান্তরিত করার জন্য React এর সাথে জাভাস্ক্রিপ্টের filter() এবং map() ব্যবহার করতে পারেন।

অ্যারের প্রতিটা আইটেমের জন্য, আপনাকে একটা key নির্দিষ্ট করতে হবে। আপনি সাধারণত ডেটাবেইজ থেকে একটা আইডিকে key হিসেবে ব্যবহার করতে চাইবেন। লিস্টে কোন আইটেমটা কোথায় আছে ট্র্যাক রাখতে React কী-গুলো ব্যবহার করতে পারে, এমনকি লিস্টে পরিবর্তন আসলেও এটা কাজ করে।

import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}

এই বিষয়ে শিখতে প্রস্তুত তো?

কীভাবে একটা কম্পোনেন্টের লিস্ট রেন্ডার করবেন এবং কীভাবে একটা key নির্দিষ্ট করবেন জানতে পড়ুন লিস্টের রেন্ডারিং।

আরো পড়ুন

কম্পোনেন্ট pure রাখা

কিছু কিছু জাভাস্ক্রিপ্ট ফাংশন pure. একটা pure ফাংশনঃ

  • কেবলমাত্র নিজেরটাই বুঝে। এটা এর কল হবার আগে থেকে বিদ্যমান কোন অবজেক্ট বা ভ্যারিয়েবল পরিবর্তন করে না।
  • একই ইনপুটের একই আউটপুট। একই ইনপুট দেওয়া হলে একটা pure ফাংশন সব সময় একই আউটপুটই দেয়।

আপনার কোডবেইজ যত বড় হবে, কঠোরভাবে আপনার কম্পোনেন্টগুলোকে pure ফাংশন হিসেবে লেখার মাধ্যমে, আপনি খুব বিরক্তিকর এক গুচ্ছ বাগ এবং অসামাঞ্জস্যপূর্ণ আচরণ থেকে নিজেকে রক্ষা করতে পারেন। এখানে একটি impure কম্পোনেন্টের উদাহরণ দেওয়া হলঃ

let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}

আগে থেকে বিদ্যমান একটা ভ্যারিয়েবল পরিবর্তনের জায়গায় আপনি যদি একটা প্রপ পাস করে দেন তাহলেই এই কম্পোনেন্টকে pure বানিয়ে ফেলতে পারবেনঃ

function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}

এই বিষয়ে শিখতে প্রস্তুত তো?

কীভাবে pure এবং অনুমানযোগ্য ফাংশন হিসেবে কম্পোনেন্ট লিখবেন জানতে পড়ুন [কম্পোনেন্ট pure রাখা।]

আরো পড়ুন

Tree হিসেবে আপনার UI

React কম্পোনেন্ট এবং মডিউলের ভেতরকার সম্পর্ক মডেল করবার জন্য tree ব্যবহার করে।

একটা React রেন্ডার ট্রি হল কম্পোনেন্টের মাঝে থাকা প্যারেন্ট-চাইল্ড সম্পর্কের একটা প্রতিফলন।

A tree graph with five nodes, with each node representing a component. The root node is located at the top the tree graph and is labelled 'Root Component'. It has two arrows extending down to two nodes labelled 'Component A' and 'Component C'. Each of the arrows is labelled with 'renders'. 'Component A' has a single 'renders' arrow to a node labelled 'Component B'. 'Component C' has a single 'renders' arrow to a node labelled 'Component D'.
A tree graph with five nodes, with each node representing a component. The root node is located at the top the tree graph and is labelled 'Root Component'. It has two arrows extending down to two nodes labelled 'Component A' and 'Component C'. Each of the arrows is labelled with 'renders'. 'Component A' has a single 'renders' arrow to a node labelled 'Component B'. 'Component C' has a single 'renders' arrow to a node labelled 'Component D'.

React রেন্ডার ট্রিয়ের একটি উদাহরণ।

ট্রি এর শীর্ষের কাছে থাকা কম্পোনেন্ট, যেগুলো রুটেরও কাছে, সেগুলোকে top-level কম্পোনেন্ট হিসেবে ধরা হয়। যেসব কম্পোনেন্টের কোন চাইল্ড নেই সেগুলোকে leaf কম্পোনেন্ট বলে। দেটা ফলো এবং রেন্ডারিং পারফরম্যান্স বুঝবার জন্য কম্পোনেন্টের এই বিভাজন কাজে লাগে।

জাভাস্ক্রিপ্ট মডিউলগুলোর মধ্যকার সম্পর্ক মডেলিং আপনার অ্যাপ বুঝবার জন্য অন্য একটি কার্যকর উপায়। এটাকে আমরা module dependency tree বলে অভিহিত করি।

A tree graph with five nodes. Each node represents a JavaScript module. The top-most node is labelled 'RootModule.js'. It has three arrows extending to the nodes: 'ModuleA.js', 'ModuleB.js', and 'ModuleC.js'. Each arrow is labelled as 'imports'. 'ModuleC.js' node has a single 'imports' arrow that points to a node labelled 'ModuleD.js'.
A tree graph with five nodes. Each node represents a JavaScript module. The top-most node is labelled 'RootModule.js'. It has three arrows extending to the nodes: 'ModuleA.js', 'ModuleB.js', and 'ModuleC.js'. Each arrow is labelled as 'imports'. 'ModuleC.js' node has a single 'imports' arrow that points to a node labelled 'ModuleD.js'.

Module dependency tree এর একটি উদাহরণ।

একটি ডিপেন্ডেন্সি ট্রি বেশিরভাগ সময় বিল্ড টুল ব্যবহার করে তৈরি করা হয়, যেন দরকারি পুরো জাভাস্ক্রিপ্ট কোড একত্রিত করে ক্লায়েন্ট ডাউনলোড এবং রেন্ডার করতে পারেন। React অ্যাপের ক্ষেত্রে একটা বড় বান্ডল সাইজ user experience এ বিঘ্ন ঘটায়। এরকম সমস্যা ডিবাগ করার জন্য মডিউল ডিপেন্ডেন্সি ট্রি কাজে লাগে।

এই বিষয়ে শিখতে প্রস্তুত তো?

Tree হিসেবে আপনার UI পড়ুন যাতে আপনি শিখতে পারেন কীভাবে একটি React অ্যাপের জন্য একটি মডিউল ডিপেন্ডেন্সি ট্রি তৈরি করতে হয় এবং রেন্ডার করতে হয় এবং কীভাবে ইউজার এক্সপিরিয়েন্স এবং পারফরম্যান্সের জন্য এগুলো কার্যকর মেন্টাল মডেল।

আরো পড়ুন

এর পর তাহলে কী?

এই অধ্যায়টি গুছিয়ে পড়া শুরু করতে চলে যান আপনার প্রথম কম্পোনেন্ট অংশে।

অথবা, বিষয়গুলো যদি আপনার আগে থেকেই জানা থাকে তাহলে, পড়ে ফেলতে পারেন ইন্টার‍্যাক্টিভিটির সংযুক্তি অংশটি!