জাভাস্ক্রিপ্টে Array হলো একটি বিশেষ ধরণের অবজেক্ট, যা তোমরা যেকোনো তথ্য সংরক্ষণ করতে ব্যবহার করতে পারো। কিন্তু যখন তুমি রিয়াক্টের স্টেট ভ্যারিয়েবল হিসেবে Array ব্যবহার করো, তখন কিছু বিষয় খেয়াল রাখা প্রয়োজন। রিয়াক্টে স্টেট পরিবর্তন করতে গিয়ে Array মিউটেট করা উচিত নয়। এর মানে হল, তুমি সরাসরি Array-এর কিছু উপাদান পরিবর্তন করতে পারবে না। বরং, তোমাকে একটি নতুন Array তৈরি করতে হবে অথবা পুরানো Array-এর কপি তৈরি করে সেখানে পরিবর্তন করতে হবে।
ধরুন, তোমার কাছে একটি Array আছে এবং তুমি সেটিতে কিছু পরিবর্তন করতে চাও। এখানে মনে রাখতে হবে, তুমি সরাসরি কিছু মিউটেট করতে পারবেনা। যেমন, arr[0] = "something" এইভাবে তুমি কোনো উপাদান পরিবর্তন করতে পারবেনা। কারণ, রিয়াক্টে স্টেট পরিবর্তন করতে গেলে তোমাকে নতুন একটি Array তৈরি করতে হবে।
এখন চলুন দেখে নেই, রিয়াক্টে Array আপডেট করার জন্য কোন মেথডগুলো ব্যবহার করা যাবে এবং কোনগুলো ব্যবহার করা উচিত নয়।
ব্যাবহারের কারণ
❌ - পুরাতন Array কে মিউটেড করে
✅ - নতুন Array রিটার্ন করে
এড করা (Adding in Array)
push, unshift
concat, [...spread], Array.of()
বাদ দেয়া (Removing from Array)
pop, shift, splice
filter, slice, toSpliced
রিপ্লেস করা (Replacing in Array)
splice, arr[0]="something"
map, toSpliced
সর্টিং করা (Sorting in Array)
sort, reverse
প্রথমে পুরাতন Array কপি করে নিয়ে sort বা reverse করা, toSorted, toReversed
যখন তুমি Array তে নতুন এলিমেন্ট যুক্ত করতে চাও, তখন push() মেথড ব্যবহার না করে concat অথবা [...spread] ব্যবহার করা উচিত। কারণ, push() মূল Array-কে মিউটেট করে।
let nextId = 0;const [artists, setArtists] = useState([ { id: 1, name: "Artist1" }, { id: 2, name: "Artist2" },]);setArtists([ ...artists, // এখানে পুরনো সব আইটেম { id: nextId++, name: "New Artist" }, // এবং নতুন একটি আইটেম]);
যদি Array এর মধ্যে কোন আইটেমকে রিপ্লেস করতে হয়, তাহলে map() মেথড ব্যবহার করা উচিত। map() দিয়ে একটি Array এর প্রতিটি আইটেমের মধ্য দিয়ে iterate করে, এবং কন্ডিশন অনুযায়ী যেই আইটেমটি রিপ্লেস করতে হবে, সেটি রিপ্লেস করা যায়।
Array এর কোনো নির্দিষ্ট পজিশনে আইটেম ইনসার্ট করতে চাইলে slice() অথবা toSpliced() ব্যবহার করা যেতে পারে। toSpliced() হল ECMA SCRIPT 2023 এর নতুন ফিচার। এটি মূল Array কে পরিবর্তন করে না এবং একটি নতুন Array রিটার্ন করে।
Array কে সরাসরি sort() অথবা reverse() মেথড ব্যবহার করে সর্ট অথবা রিভার্স করতে গেলে তা মূল Array পরিবর্তন করে দেয়। তাই সরাসরি sort() অথবা reverse() ব্যবহার না করে প্রথমে [...spread] সিনট্যাক্স ব্যবহার করে spread করে নিতে হয়।
এখানে একটা বিষয় মাথায় রাখতে হবে, [...spread] সিনট্যাক্স শুধুমাত্র প্রথম স্তরের কপি বানায়। উপরের উদাহরণ অনুযায়ী যদি শুধুমাত্র অবজেক্টগুলোর অর্ডার টা সর্ট বা রিভার্স করা হয়, তাহলে এই পদ্ধতি ঠিক আছে। কিন্তু যদি Array এর ভিতরের অবজেক্টগুলোকে কোন কিছু করতে হয়, তাহলে এইভাবে একবার [...spread] করলে চলবে না।
যখনি আমাদের Array এর ভিতরের অবজেক্টকে আপডেট করতে হবে, তখন আমরা map() ব্যবহার করে সেটা করতে পারি। যেহেতু map()Array এর প্রতিটি আইটেমের মধ্যে দিয়ে iterate করে এবং প্রতি iteration এ একেকটা আইটেম রিটার্ন করে, তাহলে map() ব্যবহার করে কন্ডিশনালি যেকোন আইটেমকে পরিবর্তন করা সম্ভব।
import { useState } from "react";let nextId = 3;const initialList = [ { id: 0, title: "Big Bellies", seen: false }, { id: 1, title: "Lunar Landscape", seen: false }, { id: 2, title: "Terracotta Army", seen: true },];export default function BucketList() { const [myList, setMyList] = useState(initialList); const [yourList, setYourList] = useState(initialList); function handleToggleMyList(artworkId, nextSeen) { setMyList( myList.map((artwork) => { if (artwork.id === artworkId) { // নতুন অবজেক্ট তৈরি করে পরিবর্তন করা হচ্ছে return { ...artwork, seen: nextSeen }; } else { // কোন পরিবর্তন নেই return artwork; } }) ); } function handleToggleYourList(artworkId, nextSeen) { setYourList( yourList.map((artwork) => { if (artwork.id === artworkId) { // নতুন অবজেক্ট তৈরি করে পরিবর্তন করা হচ্ছে return { ...artwork, seen: nextSeen }; } else { // কোন পরিবর্তন নেই return artwork; } }) ); } return ( <> <h1>Art Bucket List</h1> <h2>My list of art to see:</h2> <ItemList artworks={myList} onToggle={handleToggleMyList} /> <h2>Your list of art to see:</h2> <ItemList artworks={yourList} onToggle={handleToggleYourList} /> </> );}function ItemList({ artworks, onToggle }) { return ( <ul> {artworks.map((artwork) => ( <li key={artwork.id}> <label> <input type="checkbox" checked={artwork.seen} onChange={(e) => { onToggle(artwork.id, e.target.checked); }} /> {artwork.title} </label> </li> ))} </ul> );}