MV* Architecture Patterns (MVC, MVVM, MVP)
Flux ဆိုတာ ဘာလဲ? (ဘဏ် ဥပမာ)
Section titled “Flux ဆိုတာ ဘာလဲ? (ဘဏ် ဥပမာ)”Flux ဆိုတာ Facebook က တီထွင်ခဲ့တဲ့ Pattern ပါ။ သူ့ရဲ့ အဓိက သဘောတရားက “One Way Traffic” (တစ်လမ်းသွား) ပါ။ ဘဏ်တစ်ခုကို မြင်ယောင်ကြည့်ပါ။
- View (Customer): ငွေထုတ်ချင်တယ်။ (Button နှိပ်)
- Action (Withdrawal Slip): “10$ ထုတ်မည်” ဆိုတဲ့ စာရွက် (Slip) ဖြည့်ရတယ်။
- Dispatcher (Bank Teller): စာရွက်ကို လက်ခံပြီး စစ်ဆေးတယ်။
- Store (Vault): ငွေတိုက်ထဲက ပိုက်ဆံ လျော့သွားတယ်။ (State Update)
- View (Balance Screen): လက်ကျန်ငွေ ပြောင်းသွားတာကို မြင်ရတယ်။
Customer က ငွေတိုက်ထဲ ဝင်ပြီး ပိုက်ဆံ ယူပြေးလို့ မရပါဘူး (Direct State Mutation မရ)။ Slip ဖြည့်ပြီး Teller ကို ပေးမှ ရမှာပါ။ ဒါက Flux ရဲ့ အနှစ်သာရပါပဲ။
Redux: The Modern Flux
Section titled “Redux: The Modern Flux”Redux က Flux ကို ပိုကောင်းအောင် မွမ်းမံထားတာပါ။ အခုခေတ်မှာတော့ Redux Toolkit (RTK) ကို သုံးကြပါတယ်။
Redux Toolkit (RTK) နဲ့ ရေးပုံ
Section titled “Redux Toolkit (RTK) နဲ့ ရေးပုံ”အရင်က Redux ရေးရတာ ရှုပ်ပေမယ့် RTK မှာ createSlice နဲ့ အရမ်း လွယ်သွားပါပြီ။
import { createSlice } from '@reduxjs/toolkit';
const productsSlice = createSlice({ name: 'products', initialState: [], reducers: { addProduct: (state, action) => { // Immer library ပါဝင်တဲ့အတွက် state ကို တိုက်ရိုက်ပြင်နိုင် state.push(action.payload); }, removeProduct: (state, action) => { return state.filter(product => product.id !== action.payload.id); } }});
// Action creators တွေကို အလိုအလျောက် generate လုပ်ပေးပြီးသားexport const { addProduct, removeProduct } = productsSlice.actions;
// Reducer ကို store မှာ သုံးဖို့ export လုပ်export default productsSlice.reducer;အဓိက ပါဝင်တဲ့ အရာများ
Section titled “အဓိက ပါဝင်တဲ့ အရာများ”- Store: Application တစ်ခုလုံးရဲ့ Data တွေ သိမ်းထားတဲ့ “ဗဟိုဘဏ်”။
- Slice: Feature တစ်ခုချင်းစီအတွက် ခွဲထားတဲ့ “ဌာနခွဲ” (Product Slice, User Slice)။
- Action: “ဘာလုပ်မယ်” ဆိုတဲ့ အမိန့်စာ (
addProduct,removeProduct)။ - Reducer: အမိန့်စာကို ဖတ်ပြီး Data ပြောင်းပေးတဲ့ “မန်နေဂျာ”။
မှတ်ချက်: Redux Toolkit မှာ
state.pushလို့ ရေးလို့ ရတာက နောက်ကွယ်မှာ Immer ဆိုတဲ့ Library က ကူညီပေးနေလို့ပါ။ တကယ်တမ်း Redux က Immutable (မပြောင်းလဲနိုင်သော) ပါ။`
ဒီနည်းလမ်းက action တွေနဲ့ reducer တွေကို တစ်နေရာတည်းမှာပဲ စုစည်းထားတဲ့အတွက် ပိုပြီးရှင်းလင်းပြီး စီမံခန့်ခွဲရ လွယ်ကူစေပါတယ်။
productsSlice.actions ဆိုတာ ဘာလဲ?
Section titled “productsSlice.actions ဆိုတာ ဘာလဲ?”createSlice က reducers object ထဲမှာ သင်ရေးထားသည့် method တစ်ခုချင်းစီအတွက် action creator function ကို အလိုအလျောက် generate လုပ်ပေးပါတယ်။
ဥပမာ:
- သင်
reducersထဲမှာaddProduct(state, action)လို့ ရေးရင် ⇒productsSlice.actions.addProductဆိုတဲ့ function တစ်ခု ရရှိလာမယ် removeProductလည်း အတူတူပဲ ⇒productsSlice.actions.removeProduct
ဒီ generated action creator တွေကို destructure လုပ်ပြီး export လုပ်ချင်လို့ သုံးထားတာက export const { addProduct, removeProduct } = productsSlice.actions; ဖြစ်ပါတယ်။
Action Creator က ဘာလုပ်ပေးတာလဲ?
Section titled “Action Creator က ဘာလုပ်ပေးတာလဲ?”addProduct({ id: 1, name: 'Book' }) လို့ ခေါ်လိုက်သွားရင် Redux က အောက်ကလို action object တစ်ခုအဖြစ် အလိုအလျောက် ပြောင်းပေးတယ်:
{ type: 'products/addProduct', payload: { id: 1, name: 'Book' } }အဲဒီ type ကို သင်ကိုယ်တိုင် ရေးစရာမလိုတော့တဲ့ အတွက် Typo ပြဿနာ၊ duplication ပြဿနာတွေ လျော့နည်းစေတယ်။
ဘယ်နေရာမှာ သုံးလဲ?
Section titled “ဘယ်နေရာမှာ သုံးလဲ?”UI component ထဲက event မှာ dispatch လုပ်ဖို့သုံးတယ်
import { useDispatch } from 'react-redux';import { addProduct } from './productSlice';
function AddButton() { const dispatch = useDispatch(); return ( <button onClick={() => dispatch(addProduct({ id: Date.now(), name: 'Pen' }))}> Add </button> );}productsSlice.reducer ကို ဘာကြောင့် export default လုပ်ရတာလဲ?
Section titled “productsSlice.reducer ကို ဘာကြောင့် export default လုပ်ရတာလဲ?”Redux store တည်ဆောက်တဲ့အချိန်မှာ slice တစ်ခုချင်းစီရဲ့ reducer ကို store ကိုပေးရတယ်။ ဥပမာ -
import { configureStore } from '@reduxjs/toolkit';import productsReducer from './productSlice';
export const store = configureStore({ reducer: { products: productsReducer }});State ကို Component မှာ ဘယ်လို ဖတ်မလဲ?
Section titled “State ကို Component မှာ ဘယ်လို ဖတ်မလဲ?”import { useSelector } from 'react-redux';
function ProductList() { const products = useSelector(state => state.products); // products slice state return ( <ul> {products.map(p => <li key={p.id}>{p.name}</li>)} </ul> );}