React এর হাতেখড়ি (পর্ব ৫) — useState Hook শিখুন

useState Hook

আগের চার পর্বে আমরা যা দেখেছি সব স্ট্যাটিক ছিল — একবার রেন্ডার হওয়ার পর কিছু পাল্টায়নি। এই পর্ব থেকে শুরু হচ্ছে "State ও Interactivity" অংশ — প্রথম টপিক useState Hook, যেটা দিয়ে একটা component সময়ের সাথে পাল্টানো ডেটা "মনে রাখতে" পারে।

সমস্যাটা কী?

ধরো একটা কাউন্টার বানাতে চাও। প্রথম চেষ্টা মনে হতে পারে সাধারণ একটা ভ্যারিয়েবল দিয়ে:

function Counter() {
  let count = 0; // ❌ সাধারণ ভ্যারিয়েবল — কাজ করবে না

  function increment() {
    count = count + 1;
    console.log(count); // ভ্যারিয়েবল পাল্টাচ্ছে ঠিকই...
  }

  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>+</button>
    </div>
  );
}

এখানে count ভ্যারিয়েবল ভেতরে ভেতরে পাল্টাচ্ছে (console.log-এ দেখা যাবে), কিন্তু স্ক্রিনে দেখানো সংখ্যা কখনোই বদলাবে না! কারণ সাধারণ ভ্যারিয়েবল পাল্টালে React জানতেই পারে না যে UI আবার আঁকতে হবে (re-render করতে হবে)।

useState দিয়ে সমাধান

useState একটা "স্টেট ভ্যারিয়েবল" বানায়, যেটা পাল্টালে React স্বয়ংক্রিয়ভাবে সেই component (আর তার ভেতরের সব কিছু) আবার রেন্ডার করে।

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0); // ✅ স্টেট ভ্যারিয়েবল

  function increment() {
    setCount(count + 1); // এটা কল করলেই React আবার রেন্ডার করবে
  }

  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>+</button>
    </div>
  );
}

এখন বাটনে ক্লিক করলে স্ক্রিনে সংখ্যা ঠিকমতো বাড়বে — কারণ setCount কল করলে React বুঝতে পারে "state পাল্টেছে, UI আবার আঁকতে হবে"।

useState-এর গঠন — Array Destructuring

useState() একটা অ্যারে রিটার্ন করে — সবসময় দুইটা জিনিস: বর্তমান মান, আর সেটা পাল্টানোর একটা ফাংশন। Advanced JS পর্ব ৪-এ শেখা Array Destructuring এখানে সরাসরি কাজে লাগছে।

const [count, setCount] = useState(0);
//     ^^^^^  ^^^^^^^^         ^
//     বর্তমান মান  পাল্টানোর ফাংশন   প্রাথমিক (initial) মান

// এটা আসলে এভাবেও লেখা যেত (কিন্তু কেউ লেখে না, কারণ এটা longer):
const stateArray = useState(0);
const count = stateArray[0];
const setCount = stateArray[1];
অংশ কাজ
count বর্তমান মান — শুধু পড়ার জন্য, সরাসরি পাল্টানো যাবে না
setCount এই ফাংশন কল করেই একমাত্র মান পাল্টানো যায়
useState(0) প্রথমবার রেন্ডার হওয়ার সময় count-এর মান হবে ০

গুরুত্বপূর্ণ: count = count + 1-এর মতো সরাসরি স্টেট পাল্টানো যাবে না, শুধু setCount(...) দিয়েই পাল্টাতে হয়।

লাইভ ডেমো — কাউন্টার

নিচে একটা সম্পূর্ণ useState কাউন্টার — বাড়ানো, কমানো, আর রিসেট করার বাটন সহ।

একাধিক useState — প্রতিটা আলাদা

একটা component-এ যতগুলো দরকার ততগুলো useState কল করা যায় — প্রতিটা সম্পূর্ণ স্বাধীন, একে অপরকে প্রভাবিত করে না।

function ProfileForm() {
  const [name, setName] = useState("");
  const [age, setAge] = useState(0);
  const [isSubscribed, setIsSubscribed] = useState(false);

  // তিনটা সম্পূর্ণ আলাদা স্টেট, স্বাধীনভাবে পাল্টানো যায়
}

স্টেট অবজেক্ট বা অ্যারেও হতে পারে

useState-এ যেকোনো ধরনের ডেটা রাখা যায় — সংখ্যা, স্ট্রিং, বুলিয়ান, এমনকি অবজেক্ট বা অ্যারেও। তবে অবজেক্ট/অ্যারে পাল্টানোর সময় Advanced JS পর্ব ৫-এর Spread Operator মনে রাখতে হয় — সরাসরি মূল অবজেক্ট পাল্টানো যাবে না, নতুন একটা কপি বানাতে হয়।

function UserProfile() {
  const [user, setUser] = useState({ name: "আরিফ", age: 28 });

  function updateAge() {
    // ❌ ভুল — সরাসরি অবজেক্ট পাল্টানো, React এটা ধরতে পারবে না
    // user.age = 29;

    // ✅ ঠিক — Spread দিয়ে নতুন অবজেক্ট বানিয়ে setUser-এ দেওয়া
    setUser({ ...user, age: 29 });
  }

  return (
    <div>
      <p>{user.name}, {user.age} বছর</p>
      <button onClick={updateAge}>জন্মদিন!</button>
    </div>
  );
}

এখানে { ...user, age: 29 } — ঠিক Advanced JS পর্ব ৫-এর সেই "ইমিউটেবল আপডেট" প্যাটার্ন — একটা নতুন অবজেক্ট বানানো হচ্ছে, মূল user সরাসরি না পাল্টে। React শুধু নতুন অবজেক্ট রেফারেন্স দেখলেই বুঝতে পারে যে re-render দরকার।

Function হিসেবে setState — পুরনো মান নিরাপদে ব্যবহার

যখন নতুন স্টেট আগের স্টেটের উপর নির্ভর করে, setCount(prev => prev + 1)-এর মতো একটা ফাংশন পাস করাটা বেশি নিরাপদ, বিশেষ করে একাধিকবার দ্রুত আপডেট হলে।

function handleTripleClick() {
  // ❌ সমস্যা হতে পারে — তিনটাই পুরনো count ব্যবহার করবে, একবারই বাড়বে
  setCount(count + 1);
  setCount(count + 1);
  setCount(count + 1);

  // ✅ নিরাপদ — প্রতিটা কল সবসময় সর্বশেষ মান ব্যবহার করে
  setCount(prev => prev + 1);
  setCount(prev => prev + 1);
  setCount(prev => prev + 1);
  // এখন সত্যিই ৩ বার বাড়বে
}

একটা সম্পূর্ণ উদাহরণ — লাইক বাটন

চলো একটা বাস্তব "লাইক" বাটন বানাই, বুলিয়ান আর সংখ্যা দুটো স্টেট একসাথে ব্যবহার করে।

import { useState } from "react";

function LikeButton() {
  const [isLiked, setIsLiked] = useState(false);
  const [likeCount, setLikeCount] = useState(24);

  function handleLike() {
    setIsLiked(!isLiked);
    setLikeCount(isLiked ? likeCount - 1 : likeCount + 1);
  }

  return (
    <button onClick={handleLike} style={{ color: isLiked ? "red" : "gray" }}>
      {isLiked ? "❤️" : "🤍"} {likeCount}
    </button>
  );
}

export default LikeButton;

এখানে দুইটা স্টেট একসাথে সামঞ্জস্যপূর্ণভাবে আপডেট হচ্ছে — isLiked টগল হচ্ছে, আর সেই অনুযায়ী likeCount বাড়ছে বা কমছে।

নিজে চেষ্টা করো

Exercise:

  1. উপরের Counter component-টা নিজের Vite প্রজেক্টে বানাও — বাড়ানো, কমানো, রিসেট বাটন সহ।
  2. একটা ThemeToggle component বানাও যেখানে isDark বুলিয়ান স্টেট আছে, বাটনে ক্লিক করলে টগল হবে আর ব্যাকগ্রাউন্ড কালার পাল্টাবে।
  3. উপরের LikeButton নিজে বানাও, তারপর একই component পাশাপাশি দুইবার ব্যবহার করে দেখো প্রতিটার স্টেট আলাদা কিনা।
  4. একটা স্টেট অবজেক্ট (যেমন { name: "", email: "" }) বানাও, Spread দিয়ে একটা প্রপার্টি পাল্টানোর ফাংশন লেখো।

পরের পর্বে যা থাকছে

পরের পর্বে আমরা শিখব Event Handling বিস্তারিতভাবে — onClick, onChange-এর মতো ইভেন্ট, ইনলাইন ফাংশন বনাম আলাদা ফাংশন, আর ইভেন্ট অবজেক্ট থেকে তথ্য বের করা।

একটি মন্তব্য পোস্ট করুন

নবীনতর পূর্বতন

যোগাযোগ ফর্ম