অবশ্যই, আপনার দেওয়া ডকুমেন্টটি অনুসরণ করে, একটি সহজবোধ্য এবং বিস্তারিত ব্লগ পোস্ট তৈরি করছি। পোস্টটি তিনটি পর্বে ভাগ করা হলো, ঠিক যেমন আপনি চেয়েছেন। আমি চেষ্টা করেছি ভাষা যতটা সম্ভব সহজ রাখতে, যেন মনে হয় আপনার পাশে বসে কোনো বড় ভাই আপনাকে বিষয়গুলো বুঝিয়ে দিচ্ছে।
React State-এ Array আপডেট করবেন যেভাবে (পর্ব - ০১)
আমরা যখন React নিয়ে কাজ করি, তখন State ম্যানেজমেন্ট একটা জরুরি বিষয়। State-এর মধ্যে অবজেক্ট বা অ্যারে নিয়ে কাজ করতে গেলে প্রায়ই আমাদের কিছু জিনিস আপডেট করার দরকার হয়। আজকের এই সিরিজে আমরা শিখব কিভাবে React State-এ থাকা কোনো অ্যারে (Array) সঠিকভাবে আপডেট করতে হয়।
এই সিরিজের প্রথম পর্বে আমরা মূল ধারণা এবং কিছু বেসিক অপারেশন নিয়ে আলোচনা করব।
কেন Array সরাসরি আপডেট করা উচিত নয়?
প্রথমেই আমাদের বুঝতে হবে, জাভাস্ক্রিপ্টে অ্যারে হলো মিউটেবল (Mutable), মানে এদেরকে সরাসরি পরিবর্তন করা যায়। যেমন, আপনি চাইলেই push
, pop
বা ইনডেক্স ধরে কোনো আইটেম বদলে দিতে পারেন।
let numbers = [1, 2, 3];
numbers.push(4); // numbers এখন [1, 2, 3, 4]
numbers[0] = 99; // numbers এখন [99, 2, 3, 4]
কিন্তু React-এর দুনিয়ায় এই নিয়মটা একটু অন্যরকম। React State-এ যখন কোনো অ্যারে থাকে, তখন আমাদের সেটিকে অপরিবর্তনীয় বা ইমিউটেবল (Immutable) হিসেবে ধরতে হয়।
এখন প্রশ্ন হলো, কেন?
কারণ, React বুঝতে পারে যে তাকে কখন UI নতুন করে আঁকতে (re-render) হবে। যখন আমরা setState
ফাংশন কল করি, React পুরনো State এবং নতুন State-এর মধ্যে তুলনা করে। যদি আপনি পুরনো অ্যারের মধ্যেই কোনো আইটেম যোগ বা বিয়োগ করেন, তাহলে অ্যারের রেফারেন্স বা ঠিকানা একই থেকে যায়। ফলে, React মনে করে কোনো পরিবর্তনই হয়নি এবং UI আপডেট করে না।
তাই, আমাদের নিয়ম হলো, পুরনো অ্যারে পরিবর্তন না করে, বরং সেটির একটি নতুন কপি তৈরি করা এবং সেই নতুন কপিতে আমাদের প্রয়োজনীয় পরিবর্তনগুলো করে State আপডেট করা।
Array আপডেট করার সঠিক পদ্ধতি
চলুন দেখে নিই, অ্যারে আপডেট করার জন্য কোন মেথডগুলো এড়িয়ে চলব এবং কোনগুলো ব্যবহার করব।
কাজ | যা এড়িয়ে চলব (অ্যারে পরিবর্তন করে) | যা ব্যবহার করব (নতুন অ্যারে তৈরি করে) |
---|---|---|
যোগ করা | push , unshift | concat , [...arr] স্প্রেড সিনট্যাক্স |
বাদ দেওয়া | pop , shift , splice | filter , slice |
প্রতিস্থাপন | splice , arr[i] = ... | map |
সাজানো | reverse , sort | প্রথমে অ্যারের কপি তৈরি করা |
এখন কিছু উদাহরণ দিয়ে বিষয়গুলো আরও পরিষ্কার করা যাক।
১. অ্যারেতে নতুন আইটেম যোগ করা (Adding)
ধরুন, আমাদের একটা শিল্পীর তালিকা আছে এবং আমরা সেখানে নতুন একজন শিল্পীর নাম যোগ করতে চাই। আমরা যদি push
ব্যবহার করি, তাহলে পুরনো অ্যারেটিই পরিবর্তিত হবে, যা আমরা চাই না।
ভুল পদ্ধতি:
artists.push({
id: nextId++,
name: name,
});
সঠিক পদ্ধতি:
আমাদেরকে ...
(স্প্রেড সিনট্যাক্স) ব্যবহার করে একটি নতুন অ্যারে তৈরি করতে হবে।
setArtists([
...artists, // পুরনো অ্যারের সব আইটেম এখানে কপি হলো
{ id: nextId++, name: name }, // নতুন আইটেমটি শেষে যোগ হলো
]);
এখানে, ...artists
দিয়ে আমরা পুরনো artists
অ্যারের সব আইটেমকে একটি নতুন অ্যারের মধ্যে ছড়িয়ে দিচ্ছি এবং তার সাথে নতুন আইটেমটি যোগ করে setArtists
ফাংশনে পাঠিয়ে দিচ্ছি। React একটি নতুন অ্যারে পাওয়ায় ঠিকভাবেই UI আপডেট করবে।
আপনি যদি শুরুতে আইটেম যোগ করতে চান, তাহলে নতুন আইটেমটি আগে লিখবেন:
setArtists([
{ id: nextId++, name: name }, // নতুন আইটেমটি শুরুতে যোগ হলো
...artists,
]);
২. অ্যারে থেকে কোনো আইটেম বাদ দেওয়া (Removing)
কোনো আইটেম বাদ দেওয়ার সবচেয়ে সহজ উপায় হলো filter
মেথড ব্যবহার করা। এই মেথডটি পুরনো অ্যারের ওপর একটি শর্ত চালায় এবং সেই শর্ত যারা পূরণ করে, শুধু তাদের নিয়েই একটি নতুন অ্যারে তৈরি করে।
ধরুন, আমরা তালিকা থেকে একজন শিল্পীকে তার id
দিয়ে বাদ দিতে চাই।
setArtists(artists.filter((artist) => artist.id !== deleteId));
এখানে, artists.filter(...)
একটি নতুন অ্যারে রিটার্ন করছে, যেখানে deleteId
-এর সাথে মিলে যাওয়া শিল্পী ছাড়া বাকি সবাই উপস্থিত। filter
মেথড পুরনো অ্যারেটিকে পরিবর্তন করে না, যা আমাদের মূল উদ্দেশ্য।
৩. অ্যারের আইটেম পরিবর্তন করা (Transforming/Replacing)
যদি আমাদের অ্যারের এক বা একাধিক আইটেম পরিবর্তন করার দরকার হয়, তাহলে map
মেথড হলো আমাদের সবচেয়ে ভালো বন্ধু। map
মেথড একটি অ্যারের প্রতিটি আইটেমের ওপর একটি ফাংশন চালায় এবং সেই ফাংশন থেকে পাওয়া ফলাফলগুলো নিয়ে একটি নতুন অ্যারে তৈরি করে।
ধরুন, আমাদের কাছে কিছু কাউন্টার আছে এবং আমরা নির্দিষ্ট একটি কাউন্টারের মান বাড়াতে চাই।
function handleIncrementClick(index) {
const nextCounters = counters.map((counter, i) => {
if (i === index) {
// যে কাউন্টারে ক্লিক করা হয়েছে, তার মান ১ বাড়াও
return counter + 1;
} else {
// বাকিগুলোকে অপরিবর্তিত রাখো
return counter;
}
});
setCounters(nextCounters);
}
এখানে, map
ফাংশনটি পুরো counters
অ্যারে ঘুরে দেখছে। যখন এটি আমাদের কাঙ্ক্ষিত index
-এর আইটেমটি পাচ্ছে, তখন সেটির মান ১ বাড়িয়ে দিচ্ছে। অন্য সব আইটেমকে আগের মতোই রেখে দিচ্ছে। সবশেষে, map
একটি নতুন অ্যারে (nextCounters
) তৈরি করছে, যা দিয়ে আমরা State আপডেট করছি।
প্রথম পর্বের সারসংক্ষেপ:
- React State-এ থাকা অ্যারে সরাসরি পরিবর্তন (mutate) করা যাবে না।
- সবসময় পুরনো অ্যারের একটি কপি তৈরি করে তাতে পরিবর্তন আনতে হবে।
- আইটেম যোগ করার জন্য
[...arr, newItem]
স্প্রেড সিনট্যাক্স ব্যবহার করুন। - আইটেম বাদ দেওয়ার জন্য
filter
মেথড ব্যবহার করুন। - আইটেম পরিবর্তন বা প্রতিস্থাপনের জন্য
map
মেথড ব্যবহার করুন।
দ্বিতীয় পর্বে আমরা অ্যারে আপডেটের আরও কিছু কৌশল এবং নেস্টেড (nested) ডেটা নিয়ে কাজ করার পদ্ধতি সম্পর্কে জানব। সাথেই থাকুন!
React State-এ Array আপডেট করবেন যেভাবে (পর্ব - ০২)
আগের পর্বে আমরা React State-এ অ্যারে আপডেট করার মূল নিয়ম এবং কিছু বেসিক অপারেশন (যোগ, বিয়োগ, পরিবর্তন) নিয়ে আলোচনা করেছি। আমরা জেনেছি যে, মূল অ্যারে পরিবর্তন না করে, সবসময় একটি নতুন অ্যারে তৈরি করে State আপডেট করতে হয়।
এই পর্বে আমরা আরও কিছু জটিল পরিস্থিতি দেখব, যেমন—অ্যারের নির্দিষ্ট কোনো জায়গায় আইটেম যোগ করা, অ্যারে সাজানো (sorting) এবং সবচেয়ে গুরুত্বপূর্ণ, অ্যারের ভেতরে থাকা অবজেক্ট আপডেট করা।
৪. অ্যারের নির্দিষ্ট জায়গায় আইটেম যোগ করা (Inserting)
কখনও কখনও আমাদের অ্যারের শুরুতে বা শেষে নয়, বরং মাঝের কোনো নির্দিষ্ট অবস্থানে একটি আইটেম যোগ করার দরকার হতে পারে। এর জন্য আমরা slice
মেথড এবং ...
(স্প্রেড সিনট্যাক্স) একসাথে ব্যবহার করতে পারি।
slice
মেথড দিয়ে আমরা অ্যারের একটি অংশ কেটে নিতে পারি, কিন্তু এটি মূল অ্যারে পরিবর্তন করে না।
ধরুন, আমরা insertAt
নামক একটি ইনডেক্সে নতুন আইটেম যোগ করতে চাই।
const insertAt = 1; // ধরা যাক, আমরা ইনডেক্স ১-এ যোগ করতে চাই
const nextArtists = [
// insertAt-এর আগের আইটেমগুলো
...artists.slice(0, insertAt),
// আমাদের নতুন আইটেম
{ id: nextId++, name: name },
// insertAt-এর পরের আইটেমগুলো
...artists.slice(insertAt),
];
setArtists(nextArtists);
এখানে কী ঘটছে, চলুন ভেঙে দেখি:
artists.slice(0, insertAt)
: এটি মূল অ্যারের শুরু থেকেinsertAt
ইনডেক্সের আগ পর্যন্ত আইটেমগুলো নিয়ে একটি নতুন অ্যারে তৈরি করে।artists.slice(insertAt)
: এটিinsertAt
ইনডেক্স থেকে শুরু করে বাকি সব আইটেম নিয়ে আরেকটি নতুন অ্যারে তৈরি করে।- এরপর, আমরা এই তিনটি অংশকে (
...
স্প্রেড সিনট্যাক্স ব্যবহার করে) একটি নতুন অ্যারের মধ্যে বসিয়ে দিচ্ছি। ফলে, আমাদের নতুন আইটেমটি ঠিক জায়গায় বসে যাচ্ছে।
৫. অ্যারে রিভার্স বা সর্ট করা (Other Changes)
জাভাস্ক্রিপ্টের reverse()
এবং sort()
মেথড দুটি সরাসরি মূল অ্যারেকেই পরিবর্তন করে ফেলে। তাই React State-এর ক্ষেত্রে আমরা এগুলো সরাসরি ব্যবহার করতে পারি না।
তাহলে উপায় কী? খুবই সহজ! প্রথমে আমরা অ্যারেটির একটি কপি তৈরি করব, তারপর সেই কপির ওপর এই মেথডগুলো চালাব।
function handleReverseClick() {
// প্রথমে ... দিয়ে একটি কপি তৈরি করি
const nextList = [...list];
// এখন কপির ওপর reverse() চালাই
nextList.reverse();
// নতুন এই কপি করা এবং পরিবর্তিত অ্যারে দিয়ে স্টেট আপডেট করি
setList(nextList);
}
এভাবে আমরা মূল State অপরিবর্তিত রেখেও অ্যারে সর্ট বা রিভার্স করার মতো কাজগুলো করতে পারি।
৬. সবচেয়ে গুরুত্বপূর্ণ: অ্যারের ভেতরে অবজেক্ট আপডেট করা
এটি খুবই সাধারণ একটি পরিস্থিতি যেখানে আমরা প্রায়ই ভুল করে থাকি। ধরুন, আপনার অ্যারের ভেতরে প্রতিটি আইটেম হলো একটি করে অবজেক্ট। যেমন:
const initialList = [
{ id: 0, title: "Big Bellies", seen: false },
{ id: 1, title: "Lunar Landscape", seen: false },
{ id: 2, title: "Terracotta Army", seen: true },
];
এখন যদি আপনি একটি আইটেমের seen
প্রপার্টি true
থেকে false
করতে চান, তাহলে কী করবেন?
অনেকেই যে ভুলটি করেন:
// ভুল পদ্ধতি
const artwork = myList.find((a) => a.id === artworkId);
artwork.seen = nextSeen; // সরাসরি অবজেক্ট পরিবর্তন করা হচ্ছে
setMyList(myList); // React কোনো পরিবর্তন ধরতেই পারবে না
এমনকি যদি আপনি অ্যারের একটি কপিও তৈরি করেন, তাহলেও সমস্যা থেকেই যায়:
// এটাও ভুল পদ্ধতি
const myNextList = [...myList]; // অ্যারের কপি হলো, কিন্তু ভেতরের অবজেক্টগুলোর নয়
const artwork = myNextList.find((a) => a.id === artworkId);
artwork.seen = nextSeen; // এটি এখনও মূল অবজেক্টকেই পরিবর্তন করছে
setMyList(myNextList);
কেন এটি ভুল?
কারণ, [...myList]
দিয়ে অ্যারের একটি "শ্যালো কপি" (Shallow Copy) তৈরি হয়। এর মানে হলো, অ্যারেটি নতুন, কিন্তু তার ভেতরের অবজেক্টগুলো পুরনো অ্যারের অবজেক্টগুলোই। অনেকটা ফটোকপির মতো, যেখানে আপনি শুধু বাড়ির ঠিকানার তালিকা কপি করেছেন, কিন্তু বাড়িগুলো নিজেরা কপি হয়নি। তাই যখন আপনি নতুন তালিকা ধরে কোনো বাড়ির রঙ বদলে দেবেন, তখন পুরনো তালিকা থেকেও সেই বাড়ির রঙ বদলেই দেখাবে।
সঠিক পদ্ধতি:
এই সমস্যার সমাধান হলো map
ব্যবহার করা। আমরা map
দিয়ে অ্যারেটি ঘুরে দেখব এবং যে অবজেক্টটি পরিবর্তন করতে চাই, সেটিরও একটি নতুন কপি তৈরি করব।
function handleToggleMyList(artworkId, nextSeen) {
setMyList(
myList.map((artwork) => {
if (artwork.id === artworkId) {
// এটি আমাদের কাঙ্ক্ষিত অবজেক্ট
// তাই এটির একটি কপি তৈরি করে পরিবর্তন করি
return { ...artwork, seen: nextSeen };
} else {
// বাকি অবজেক্টগুলো অপরিবর্তিত থাকবে
return artwork;
}
})
);
}
এখানে map
-এর ভেতরে, আমরা যে artwork
-এর id
মিলে যাচ্ছে, সেটিকে সরাসরি পরিবর্তন না করে, { ...artwork, seen: nextSeen }
ব্যবহার করে তার একটি নতুন কপি তৈরি করছি এবং seen
-এর মান আপডেট করে দিচ্ছি। ফলে, আমাদের কোনো ডেটাই সরাসরি পরিবর্তিত হচ্ছে না এবং React ঠিকভাবে পরিবর্তন শনাক্ত করতে পারছে।
দ্বিতীয় পর্বের সারসংক্ষেপ:
- অ্যারের মাঝে আইটেম ঢোকাতে
slice
এবং স্প্রেড সিনট্যাক্স (...
) একসাথে ব্যবহার করা যায়। sort
বাreverse
-এর মতো mutating মেথড ব্যবহার করার আগে অ্যারের একটি কপি তৈরি করে নিতে হবে।- অ্যারের ভেতরে থাকা অবজেক্ট আপডেট করার সময় শুধু অ্যারে নয়, ভেতরের অবজেক্টেরও কপি তৈরি করুন (
map
এবং{...obj}
দিয়ে)। - Immer দিয়ে জীবন সহজ করুন: জটিল বা নেস্টেড State আপডেটের জন্য Immer লাইব্রেরি ব্যবহার করুন। এটি আপনার কোডকে সংক্ষিপ্ত ও সহজবোধ্য রাখে।
পরবর্তী এবং শেষ পর্বে আমরা দেখব কিভাবে Immer
লাইব্রেরি ব্যবহার করে এই পুরো প্রক্রিয়াটিকে আরও সহজ ও সুন্দর করে তোলা যায় এবং কিছু অনুশীলন করব।
React State-এ Array আপডেট করবেন যেভাবে (পর্ব - ০৩)
প্রথম দুই পর্বে আমরা React State-এ অ্যারে আপডেট করার বিভিন্ন কৌশল শিখেছি। আমরা দেখেছি কিভাবে spread syntax (...)
, filter
, এবং map
ব্যবহার করে অ্যারের আইটেম যোগ, বিয়োগ বা পরিবর্তন করা যায়, কোনো কিছুই সরাসরি পরিবর্তন (mutate) না করে। আমরা আরও দেখেছি যে অ্যারের ভেতরে থাকা নেস্টেড অবজেক্ট আপডেট করাটা একটু জটিল হতে পারে।
এই শেষ পর্বে আমরা জানব কিভাবে এই জটিল কাজগুলোকে অনেক সহজ করে ফেলা যায় Immer
নামক একটি লাইব্রেরির সাহায্যে এবং সবশেষে কিছু অনুশীলন করব।
কোডকে সহজ করার জাদুকর: Immer
যখন আমাদের State-এর গঠন বেশ গভীর বা নেস্টেড (nested) হয়ে যায়, তখন map
বা spread syntax
দিয়ে কোড লেখাটা একটু কষ্টকর ও পুনরাবৃত্তিমূলক মনে হতে পারে। যেমন, একটি অ্যারের ভেতরের কোনো অবজেক্টের ভেতরের আরেকটি অ্যারে আপডেট করা বেশ জটিল হতে পারে।
এই ধরনের পরিস্থিতি সহজ করার জন্য একটি চমৎকার লাইব্রেরি হলো Immer।
Immer কী করে?
Immer আপনাকে অনুমতি দেয় যেন আপনি সরাসরি State পরিবর্তন করছেন, এমন কোড লিখতে পারেন। অর্থাৎ, আপনি push
, pop
বা object.property = value
-এর মতো সহজ ও পরিচিত কোড লিখতে পারবেন। পর্দার আড়ালে, Immer আপনার এই "মিউটেটিং" কোডকে ট্র্যাক করে এবং নিজে থেকেই একটি সঠিক, অপরিবর্তনীয় (immutable) নতুন State তৈরি করে দেয়।
আপনাকে আর কষ্ট করে ধাপে ধাপে কপি তৈরি করতে হয় না।
চলুন, আগের পর্বের নেস্টেড অবজেক্ট আপডেটের উদাহরণটি Immer দিয়ে কেমন হবে, তা দেখি।
Immer ছাড়া কোড:
function handleToggleMyList(artworkId, nextSeen) {
setMyList(
myList.map((artwork) => {
if (artwork.id === artworkId) {
return { ...artwork, seen: nextSeen };
} else {
return artwork;
}
})
);
}
Immer ব্যবহার করে কোড:
প্রথমে আপনাকে use-immer
হুক ব্যবহার করতে হবে।
import { useImmer } from "use-immer";
// ... component ...
const [myList, updateMyList] = useImmer(initialList);
function handleToggleMyList(artworkId, nextSeen) {
updateMyList((draft) => {
const artwork = draft.find((a) => a.id === artworkId);
artwork.seen = nextSeen;
});
}
দেখুন, কোডটি কত সহজ হয়ে গেল!
এখানে updateMyList
-এর ভেতরে আমরা একটি ফাংশন পাস করেছি, যা draft
নামক একটি প্যারামিটার পায়। এই draft
হলো আপনার State-এর একটি অস্থায়ী এবং পরিবর্তনযোগ্য সংস্করণ। আপনি এই draft
-এর ওপর আপনার সব পরিবর্তন (যেমন find
করে seen
-এর মান বদলে দেওয়া) নিশ্চিন্তে করতে পারেন। আপনার কাজ শেষ হলে, Immer নিজে থেকেই সবকিছু তুলনা করে একটি নতুন, অপরিবর্তনীয় State তৈরি করে দেবে।
Immer ব্যবহার করলে আপনার কোড যেমন পরিষ্কার হয়, তেমনই ভুল হওয়ার সম্ভাবনাও অনেক কমে যায়।
সম্পূর্ণ সিরিজের সারসংক্ষেপ
চলুন, আমরা এই তিন পর্বের সিরিজ থেকে যা যা শিখলাম, তা একনজরে দেখে নিই:
- State-কে অপরিবর্তনীয় ভাবুন: React-এ State (অবজেক্ট বা অ্যারে) সরাসরি পরিবর্তন করা উচিত নয়।
- নতুন কপি তৈরি করুন: পুরনো ডেটা পরিবর্তন না করে, সবসময় সেটির একটি নতুন কপি তৈরি করে তাতে পরিবর্তন আনুন এবং
setState
কল করুন। - সঠিক টুল ব্যবহার করুন:
- আইটেম যোগ করতে:
[...arr, newItem]
- আইটেম বাদ দিতে:
arr.filter()
- আইটেম পরিবর্তন করতে:
arr.map()
- আইটেম যোগ করতে:
- নেস্টেড ডেটার ক্ষেত্রে সতর্ক থাকুন: অ্যারের ভেতরের অবজেক্ট আপডেট করার সময় শুধু অ্যারে নয়, ভেতরের অবজেক্টেরও কপি তৈরি করুন (
map
এবং{...obj}
দিয়ে)। - Immer দিয়ে জীবন সহজ করুন: জটিল বা নেস্টেড State আপডেটের জন্য Immer লাইব্রেরি ব্যবহার করুন। এটি আপনার কোডকে সংক্ষিপ্ত ও সহজবোধ্য রাখে।
এবার আপনার পালা: কিছু অনুশীলন
জ্ঞানকে পাকাপোক্ত করার সেরা উপায় হলো অনুশীলন করা। নিচে কয়েকটি চ্যালেঞ্জ দেওয়া হলো, যা আপনি নিজে সমাধান করার চেষ্টা করতে পারেন।
চ্যালেঞ্জ ১: শপিং কার্টের আইটেম আপডেট করুন
নিচের কোডে handleIncreaseClick
ফাংশনটি পূরণ করুন, যেন "+" বাটনে ক্লিক করলে সংশ্লিষ্ট পণ্যের সংখ্যা (count) এক করে বাড়ে।
<details> <summary>সমাধান দেখুন</summary>
import { useState } from "react";
const initialProducts = [
{
id: 0,
name: "Baklava",
count: 1,
},
{
id: 1,
name: "Cheese",
count: 5,
},
{
id: 2,
name: "Spaghetti",
count: 2,
},
];
export default function ShoppingCart() {
const [products, setProducts] = useState(initialProducts);
function handleIncreaseClick(productId) {
setProducts(
products.map((product) => {
if (product.id === productId) {
return {
...product,
count: product.count + 1,
};
} else {
return product;
}
})
);
}
return (
<ul>
{products.map((product) => (
<li key={product.id}>
{product.name} (<b>{product.count}</b>)
<button
onClick={() => {
handleIncreaseClick(product.id);
}}
>
+
</button>
</li>
))}
</ul>
);
}
</details>
চ্যালেঞ্জ ২: শপিং কার্ট থেকে আইটেম বাদ দিন
এইবার উপরের শপিং কার্টে একটি "–" বাটন যোগ করুন এবং এর জন্য handleDecreaseClick
ফাংশন লিখুন। বাটনে ক্লিক করলে পণ্যের সংখ্যা কমবে। যদি কোনো পণ্যের সংখ্যা ১ থাকে এবং "–" বাটনে ক্লিক করা হয়, তবে পণ্যটি কার্ট থেকে মুছে যাবে।
<details> <summary>সমাধান দেখুন</summary>
function handleDecreaseClick(productId) {
let nextProducts = products.map((product) => {
if (product.id === productId) {
return {
...product,
count: product.count - 1,
};
} else {
return product;
}
});
// যে সব পণ্যের count শূন্য হয়ে গেছে, সেগুলোকে বাদ দাও
nextProducts = nextProducts.filter((p) => p.count > 0);
setProducts(nextProducts);
}
এখানে আমরা প্রথমে map
দিয়ে সংখ্যা কমাচ্ছি এবং তারপর filter
দিয়ে সেই পণ্যগুলো বাদ দিচ্ছি, যাদের count
শূন্য হয়ে গেছে।
</details>
আশা করি, এই সিরিজটি আপনাকে React-এ অ্যারে স্টেট ম্যানেজমেন্টের ধারণাটি পরিষ্কারভাবে বুঝতে সাহায্য করেছে। শুভ কোডিং!