State Management
What is State Management?
প্রযুক্তিগতভাবে, প্রতিটি Vue কম্পোনেন্ট ইন্সট্যান্স ইতিমধ্যেই তার নিজস্ব প্রতিক্রিয়াশীল অবস্থা "পরিচালনা" করে। একটি উদাহরণ হিসাবে একটি সাধারণ কাউন্টার কম্পোনেন্ট নিন:
vue
<script setup>
import { ref } from 'vue'
// state
const count = ref(0)
// actions
function increment() {
count.value++
}
</script>
<!-- view -->
<template>{{ count }}</template>
এটি নিম্নলিখিত অংশগুলির সাথে একটি স্বয়ংসম্পূর্ণ ইউনিট:
- state, সত্যের উৎস যা আমাদের অ্যাপকে চালিত করে;
- view, state এর একটি ডিক্লেয়ার ম্যাপিং;
- actions, view থেকে ব্যবহারকারীর ইনপুটগুলির প্রতিক্রিয়ায় রাষ্ট্র পরিবর্তন করতে পারে এমন সম্ভাব্য উপায়।
এটি "one-way data flow" ধারণার একটি সহজ উপস্থাপনা:
যাইহোক, সরলতা ভেঙ্গে যেতে শুরু করে যখন আমাদের কাছে একাধিক components থাকে যা একটি সাধারণ অবস্থা ভাগ করে:
- একাধিক ভিউ একই রাজ্যের উপর নির্ভর করতে পারে।
- বিভিন্ন দৃষ্টিভঙ্গি থেকে ক্রিয়াকলাপের জন্য একই state অংশকে পরিবর্তন করতে হতে পারে।
প্রথম ক্ষেত্রে, একটি সম্ভাব্য সমাধান হল শেয়ার্ড স্টেটটিকে একটি সাধারণ পূর্বপুরুষ কম্পোনেন্ট পর্যন্ত "উঠিয়ে" এবং তারপর এটিকে প্রপস হিসাবে নামিয়ে দেওয়া। যাইহোক, এটি গভীর শ্রেণিবিন্যাস সহ কম্পোনেন্ট গাছগুলিতে দ্রুত ক্লান্তিকর হয়ে ওঠে, যার ফলে আরেকটি সমস্যা হয় যা Prop Drilling.
দ্বিতীয় ক্ষেত্রে, আমরা প্রায়শই নিজেদেরকে সমাধানের অবলম্বন করতে দেখি যেমন টেমপ্লেট রেফের মাধ্যমে সরাসরি পিতামাতা/ চাইল্ডদের কাছে পৌঁছানো, বা নির্গত ইভেন্টের মাধ্যমে রাষ্ট্রের একাধিক অনুলিপি পরিবর্তন এবং সিঙ্ক্রোনাইজ করার চেষ্টা করা। এই দুটি প্যাটার্নই ভঙ্গুর এবং দ্রুত অরক্ষণীয় কোডের দিকে নিয়ে যায়।
একটি সহজ এবং আরও সরল সমাধান হ'ল অংশগুলি থেকে ভাগ করা রাজ্যটি বের করা এবং এটি একটি বিশ্বব্যাপী এককটনে পরিচালনা করা। এটির সাথে, আমাদের কম্পোনেন্ট গাছটি একটি বড় "ভিউ" হয়ে যায় এবং যে কোনও কম্পোনেন্ট রাজ্যে অ্যাক্সেস করতে পারে বা ট্রিগার অ্যাকশনগুলিকে ট্রিগার করতে পারে, তারা গাছের মধ্যে যেখানেই থাকুক না কেন!
Simple State Management with Reactivity API
আপনার যদি state একটি অংশ থাকে যা একাধিক দৃষ্টান্ত দ্বারা ভাগ করা উচিত, আপনি একটি প্রতিক্রিয়াশীল অবজেক্ট তৈরি করতে reactive()
ব্যবহার করতে পারেন, এবং তারপর এটিকে একাধিক কম্পোনেন্টে আমদানি করতে পারেন:
js
// store.js
import { reactive } from 'vue'
export const store = reactive({
count: 0
})
vue
<!-- ComponentA.vue -->
<script setup>
import { store } from './store.js'
</script>
<template>From A: {{ store.count }}</template>
vue
<!-- ComponentB.vue -->
<script setup>
import { store } from './store.js'
</script>
<template>From B: {{ store.count }}</template>
এখন যখনই store
অবজেক্ট পরিবর্তিত হয়, <ComponentA>
এবং <ComponentB>
উভয়ই তাদের মতামত স্বয়ংক্রিয়ভাবে আপডেট করবে - আমাদের কাছে এখন সত্যের একক উৎস আছে।
যাইহোক, এর মানে store
আমদানি করা যেকোন কম্পোনেন্ট এটিকে পরিবর্তন করতে পারে যেভাবে তারা চায়:
template
<template>
<button @click="store.count++">
From B: {{ store.count }}
</button>
</template>
যদিও এটি সাধারণ ক্ষেত্রে কাজ করে, বৈশ্বিক রাষ্ট্র যা কোনো কম্পোনেন্ট দ্বারা নির্বিচারে পরিবর্তিত হতে পারে তা দীর্ঘমেয়াদে খুব রক্ষণাবেক্ষণযোগ্য হবে না। স্টেট-মিউটেটিং লজিক রাজ্যের মতোই কেন্দ্রীভূত হয় তা নিশ্চিত করার জন্য, দোকানে এমন নামগুলির সাথে পদ্ধতিগুলি সংজ্ঞায়িত করার সুপারিশ করা হয় যা ক্রিয়াগুলির অভিপ্রায় প্রকাশ করে:
js
// store.js
import { reactive } from 'vue'
export const store = reactive({
count: 0,
increment() {
this.count++
}
})
template
<template>
<button @click="store.increment()">
From B: {{ store.count }}
</button>
</template>
TIP
মনে রাখবেন ক্লিক হ্যান্ডলার বন্ধনী সহ store.increment()
ব্যবহার করে - এটি একটি কম্পোনেন্ট পদ্ধতি না হওয়ায় সঠিক this
প্রসঙ্গ সহ পদ্ধতিটিকে কল করতে হবে।
যদিও এখানে আমরা একটি দোকান হিসাবে একটি একক প্রতিক্রিয়াশীল অবজেক্ট ব্যবহার করছি, আপনি অন্যান্য রিঅ্যাকটিভিটি API যেমন ref()
বা কম্পিউটেড()
, অথবা এমনকি ব্যবহার করে তৈরি প্রতিক্রিয়াশীল অবস্থাও ভাগ করতে পারেন। একটি কম্পোজযোগ্য থেকে বৈশ্বিক অবস্থা ফেরত দিন:
js
import { ref } from 'vue'
// global state, created in module scope
const globalCount = ref(1)
export function useCount() {
// local state, created per-component
const localCount = ref(1)
return {
globalCount,
localCount
}
}
Vue এর প্রতিক্রিয়াশীলতা সিস্টেমটি কম্পোনেন্ট মডেল থেকে বিচ্ছিন্ন হওয়ার কারণে এটিকে অত্যন্ত নমনীয় করে তোলে।
SSR Considerations
আপনি যদি এমন একটি অ্যাপ্লিকেশন তৈরি করেন যা সার্ভার-সাইড রেন্ডারিং (SSR) ব্যবহার করে, তবে উপরের প্যাটার্নটি একাধিক অনুরোধে শেয়ার করা একটি সিঙ্গলটন হওয়ার কারণে সমস্যা হতে পারে। SSR নির্দেশিকায় আরো বিশদ বিবরণ এ নিয়ে আলোচনা করা হয়েছে।
Pinia
যদিও আমাদের হ্যান্ড-রোল্ড স্টেট ম্যানেজমেন্ট সলিউশন সাধারণ পরিস্থিতিতে যথেষ্ট হবে, বৃহৎ-স্কেল উত্পাদন অ্যাপ্লিকেশনগুলিতে আরও অনেক বিষয় বিবেচনা করতে হবে:
- দলের সহযোগিতার জন্য শক্তিশালী সম্মেলন
- টাইমলাইন, ইন- কম্পোনেন্ট পরিদর্শন এবং টাইম-ট্রাভেল ডিবাগিং সহ Vue DevTools-এর সাথে ব্যবহার করা
- হট মডিউল প্রতিস্থাপন
- সার্ভার-সাইড রেন্ডারিং সমর্থন
Pinia হল একটি রাষ্ট্রীয় ব্যবস্থাপনা লাইব্রেরি যা উপরোক্ত সবগুলো বাস্তবায়ন করে। এটি Vue কোর টিম দ্বারা রক্ষণাবেক্ষণ করা হয় এবং Vue 2 এবং Vue 3 উভয়ের সাথেই কাজ করে।
বর্তমান ব্যবহারকারীরা হয়তো Vuex, Vue-এর আগের অফিসিয়াল স্টেট ম্যানেজমেন্ট লাইব্রেরির সাথে পরিচিত। পিনিয়া ইকোসিস্টেমে একই ভূমিকা পালন করে, Vuex এখন রক্ষণাবেক্ষণ মোডে রয়েছে। এটি এখনও কাজ করে, তবে আর নতুন বৈশিষ্ট্য পাবে না। নতুন অ্যাপ্লিকেশনের জন্য পিনিয়া ব্যবহার করার পরামর্শ দেওয়া হয়।
পিনিয়া Vuex এর পরবর্তী পুনরাবৃত্তি কেমন হতে পারে তার একটি অন্বেষণ হিসাবে শুরু করেছিল, Vuex 5 এর জন্য মূল দলের আলোচনা থেকে অনেক ধারনা একত্রিত করে। অবশেষে, আমরা বুঝতে পেরেছি যে পিনিয়া ইতিমধ্যেই Vuex 5-এ আমরা যা চেয়েছিলাম তার বেশিরভাগই বাস্তবায়ন করেছে এবং এটি করার সিদ্ধান্ত নিয়েছে। পরিবর্তে নতুন সুপারিশ.
Vuex-এর তুলনায়, Pinia কম অনুষ্ঠানের সাথে একটি সহজ API প্রদান করে, Composition-API-স্টাইল API গুলি অফার করে এবং সবচেয়ে গুরুত্বপূর্ণভাবে, TypeScript-এর সাথে ব্যবহার করার সময় কঠিন ধরনের অনুমান সমর্থন থাকে।