✨MVVM in React
MVVM architectural design pattern
คุณเคยเปิด project และบอบช้ำเมื่อเห็น code หรือไม่ ? คุณไม่ต้องการแตะต้องมัน หรือ สัมผัสมัน เพราะถ้าคุณสัมผัสมัน ทุกอย่างดูเหมือนจะพร้อมพังทลายได้ตลอดเวลา อย่างเช่นภาพด้านล่างนี้

การเริ่มต้นเขียน code นั้นดูเหมือนอะไรๆก็ง่าย หาก project นั้นเป็นโปรเจคขนาดเล็ก แต่ถ้า project นั้นใหญ่ขึ้นแน่นอน code ก็จะมีความซับซ้อนตามมา คงไม่มีใครอยากกลับมาแตะต้อง code ที่มันทำงานได้ดีอยู่แล้ว และ หากคุณไม่มีการจัดระเบียบ code ที่ดี ก็ส่งผลทำให้การดูแลและการบำรุงรักษานั้นเป็นเรื่องที่ยาก ดังนั้น ในบทความนี้ เราจะมาดูกันว่าคุณสามารถใช้รูปแบบสถาปัตยกรรม Model-View-ViewModel (MVVM) ในโปรเจ็กต์ React และปรับปรุงคุณภาพโค้ดได้ยังไง เพื่อสร้างแอปพลิเคชัน React ที่สามารถปรับขนาดและบำรุงรักษาได้
By definition, an Architecture Pattern provides a set of predefined subsystems, specifies their responsibilities, and includes rules and guidelines for organising the relationship between them.

What is MVVM?
MVVM คือ architectural design pattern รูปแบบหนึ่งที่ช่วยในเรื่องของการ scalable และ maintainable โดย MVVM จะแยกส่วนประกอบที่ชัดเจนทำให้การพัฒนา ทดสอบ และ บำรุงรักษา Application ของเราให้ง่ายขึ้น
โดยนิยามแล้วหัวใจหลักของ MVVM คือ แยก code ออกเป็น Models , Views และ ViewModels โดยที่ Views มีหน้าที่รับผิดชอบในการแสดงผลข้อมูลแก่ผู้ใช้(UI) ViewModels จะทำหน้าที่เป็นสื่อกลางระหว่าง Views และ Models (Logic) และ Models จะจัดการข้อมูลแอปพลิเคชัน
The View — UI layer that users interact with,
The ViewModel — has access to the Model and handles business logic,
The Model — application data source
+---------------------------+
| View |
+---------------------------+
| ^
v |
+---------------------------+
| ViewModel |
+---------------------------+
| ^
v |
+---------------------------+
| Model |
+---------------------------+
ตัวอย่าง วิธีใช้งาน hooks และ Redux ในการเขียนแบบ MVVM architecture?
The Model
// store.js
import { createStore } from 'redux';
import rootReducer from './reducers';
const store = createStore(rootReducer);
export { store };
// reducers.js
const initialState = {
counter: 0,
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return {
...state,
counter: state.counter + 1,
};
case 'DECREMENT':
return {
...state,
counter: state.counter - 1,
};
default:
return state;
}
};
export { rootReducer };
The ViewModel
import { useSelector, useDispatch } from 'react-redux';
const useCounterViewModel = () => {
const counter = useSelector((state) => state.counter);
const dispatch = useDispatch();
const increment = () => {
dispatch({ type: 'INCREMENT' });
};
const decrement = () => {
dispatch({ type: 'DECREMENT' });
};
return {
counter,
increment,
decrement,
};
};
export { useCounterViewModel } ;
The View
import { useCounterViewModel } from './useCounterViewModel';
function App() {
const { count, increment, decrement } = useCounter();
return (
<>
<div>
<h1>{count}</h1>
<button onClick={() => increment()}>+</button>
<button onClick={() => decrement()}>-</button>
</div>
</>
);
}
export default App;
What is MVVM’s purpose?
ส่วนใหญ่การเขียนแบบ MVVM จะมีวัตถุประสงค์สำหรับใช้ทดสอบการเขียน Unitest เพราะเป็นการแยก Logic ออกจาก UI ทำให้เราสามารถทดสอบแยกเป็นส่วนๆได้ เราไม่จำเป็นต้อง Render ทั้ง Component หรือ UI ทั้งหมด เราสามารถเขียน pure business logic และทดสอบผลลัพธ์แค่ในส่วนนั้นๆได้ อีกทั้งยังช่วยให้ code ดูอ่านง่ายขึ้น และยังช่วยให้สามารถนำ code ในส่วนนั้นๆ มาใช้ซ้ำได้มากขึ้นเนื่องจากไม่มีตรรกะที่เกี่ยวข้องกับ UI
สรุป นิยาม MVVM แบบฉบับ OMS
Model = The Model is composed of the Redux (store + reducer)
View = The View is just a view, the visuals look (JSX, CSS)
ViewModel = The ViewModel is composed of a Container Component and a Hook (business logic)
Ref
1.https://www.perssondennis.com/articles/how-to-use-mvvm-in-react-using-hooks-and-typescript
2.https://www.detroitlabs.com/blog/intro-to-mvvm-in-react-with-mobx/
3.https://www.detroitlabs.com/blog/intro-to-mvvm-in-react-with-mobx/
4.https://medium.cobeisfresh.com/level-up-your-react-architecture-with-mvvm-a471979e3f21
5.https://stackoverflow.com/questions/62684996/react-hooks-with-redux-mvvm-architecture
Last updated