Devahoy Logo
PublishedAt

React

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

มาใช้ 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

Terminal window
npm install zustand
# yarn
yarn add zustand
#pnpm
pnpm add zustand

ตัวอย่าง App Counter ด้วย TypeScript

1
import { create } from 'zustand'
2
3
type Store = {
4
count: number
5
inc: () => void
6
}
7
8
const useStore = create<Store>()((set) => ({
9
count: 1,
10
inc: () => set((state) => ({ count: state.count + 1 }))
11
}))
12
13
function Counter() {
14
const { count, inc } = useStore()
15
return (
16
<div>
17
<span>{count}</span>
18
<button onClick={inc}>one up</button>
19
</div>
20
)
21
}

จากโค๊ดด้านบน เราจะเห็นว่า

  • เรากำหนด type Store โดยมี count และ inc เป็น function
  • function create ของ zustand เป็น hook function สำหรับสร้าง store ถ้ามองดีๆรูปแบบมันคือ create<T>()(...)
  • ตัว useStore ที่เราได้จาก create เป็น hook ฉะนั้น เราก็สามารถเรียกใช้งานใน Component ของเราได้เลย โดยไม่ต้องมี Provider
1
const { count, inc } = useStore()
  • ถ้า component นั้นมีการใช้ state ใน store ก็จะทำการ re-render เหมือน state ปกติใน component

Multiple States

สมมติเรามีข้อมูล state ที่เก็บใน store เยอะมากๆ เช่น มีพวก name, score, message เพิ่มเข้าไป

1
type Store = {
2
count: number
3
name: string
4
score: number
5
message: string
6
inc: () => void
7
}

หากเราใช้แบบด้านล่างนี้ มันจะ re-render component ทุกครั้งที่ state เปลี่ยน

1
const state = useStore()

ส่วนมากจะใช้วิธี state slices เอาแค่ state ที่เราต้องการใช้ใน component นั้นๆ เช่น

1
const name = useStore((state) => state.name)
2
const message = useStore((state) => state.message)

หรือหากใครเคยใช้ mapStateToProps แบบ Redux เราสามารถใช้เป็น single object ได้ โดยใช้ shallow แบบนี้

1
import { shallow } from 'zustand'
2
3
const { name, message } = useStore((state) => ({ name: state.name, message: state.message }))
4
5
// ใน useStore รับ fn ที่รับ state เป็น args แล้ว return เป็น object
6
// function(state) {
7
// return { name: state.name, message: state.message }
8
// }

สรุป

ก็หวังว่าบทความนี้จะมีประโยชน์สำหรับคนที่สนใจ Zustand และการจัดการ State บน React.js แม้ว่า ตัวอย่างส่วนใหญ่ จริงๆ ก็คืออ่านจาก Docs นั่นแหละ และก็ลองนำมาประยุกต์ ปรับใช้งานดูครับ นอกจากนี้ ก็ลองอ่า Recipes เพิ่มเติม รวมถึง TypesScript Guide

Happy Coding ❤️

Authors
avatar

Chai Phonbopit

เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust

Related Posts