มาใช้ Zustand ร่วมกับ React + TypeScript กันดีกว่า

สวัสดีครับ วันนี้ขอมาเขียนบล็อก วิธีการใช้งาน Zustand ร่วมกับ React.js + TypeScript เผื่อใครไม่รู้ตัว Zustand เป็น State Management library ตัวนึงของ React (ซึ่งมีอีกมากมายในกลุ่มนี้)
ข้อดีของ Zustand
ส่วนตัวผมมองว่ามีข้อดีประมาณนี้
- มันไม่ยุ่งยากเท่ากับ Redux เขียนและอ่านง่ายกว่า
- ไม่จำเป็นต้องเอาพวก Context Provider มาหุ้มตัว App หรือ Container เราแบบ Context API
- เป็น Centralize คล้ายๆ global state
การใช้งาน Zustand ก็ง่ายๆ แค่ติดตั้งผ่าน npm/yarn หรือ pnpm
npm install zustand
# yarnyarn add zustand
#pnpmpnpm add zustand
ตัวอย่าง App Counter ด้วย TypeScript
import { create } from 'zustand'
type Store = { count: number inc: () => void}
const useStore = create<Store>()((set) => ({ count: 1, inc: () => set((state) => ({ count: state.count + 1 }))}))
function Counter() { const { count, inc } = useStore() return ( <div> <span>{count}</span> <button onClick={inc}>one up</button> </div> )}
จากโค๊ดด้านบน เราจะเห็นว่า
- เรากำหนด type Store โดยมี count และ inc เป็น function
- function create ของ zustand เป็น hook function สำหรับสร้าง store ถ้ามองดีๆรูปแบบมันคือ
create<T>()(...)
- ตัว useStore ที่เราได้จาก create เป็น hook ฉะนั้น เราก็สามารถเรียกใช้งานใน Component ของเราได้เลย โดยไม่ต้องมี Provider
const { count, inc } = useStore()
- ถ้า component นั้นมีการใช้ state ใน store ก็จะทำการ re-render เหมือน state ปกติใน component
Multiple States
สมมติเรามีข้อมูล state ที่เก็บใน store เยอะมากๆ เช่น มีพวก name, score, message เพิ่มเข้าไป
type Store = { count: number name: string score: number message: string inc: () => void}
หากเราใช้แบบด้านล่างนี้ มันจะ re-render component ทุกครั้งที่ state เปลี่ยน
const state = useStore()
ส่วนมากจะใช้วิธี state slices เอาแค่ state ที่เราต้องการใช้ใน component นั้นๆ เช่น
const name = useStore((state) => state.name)const message = useStore((state) => state.message)
หรือหากใครเคยใช้ mapStateToProps แบบ Redux เราสามารถใช้เป็น single object ได้ โดยใช้ shallow แบบนี้
import { shallow } from 'zustand'
const { name, message } = useStore((state) => ({ name: state.name, message: state.message }))
// ใน useStore รับ fn ที่รับ state เป็น args แล้ว return เป็น object// function(state) {// return { name: state.name, message: state.message }// }
สรุป
ก็หวังว่าบทความนี้จะมีประโยชน์สำหรับคนที่สนใจ Zustand และการจัดการ State บน React.js แม้ว่า ตัวอย่างส่วนใหญ่ จริงๆ ก็คืออ่านจาก Docs นั่นแหละ และก็ลองนำมาประยุกต์ ปรับใช้งานดูครับ นอกจากนี้ ก็ลองอ่า Recipes เพิ่มเติม รวมถึง TypesScript Guide
Happy Coding ❤️
- Authors
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust