Redux คือคอนเทนเนอร์จัดการสถานะที่คาดเดาได้สำหรับแอปพลิเคชัน JavaScript สร้างโดย Dan Abramov ในปี 2015 Redux ใช้การไหลของข้อมูลทางเดียวตามสถาปัตยกรรม Flux: สถานะถูกจัดเก็บใน Store เดียว เปลี่ยนแปลงผ่านฟังก์ชัน Reducer บริสุทธิ์เท่านั้น และเริ่มต้นผ่าน Action พร้อม Dispatch จากข้อมูลของ npm Trends Redux มียอดดาวน์โหลดมากกว่า 7 ล้านครั้งต่อสัปดาห์ ยังคงเป็นมาตรฐานสำหรับการจัดการสถานะใน React Native และแอปพลิเคชันเว็บ
ประเด็นสำคัญ
Redux คือรูปแบบสถาปัตยกรรมและไลบรารีสำหรับการจัดการสถานะ บนพื้นฐานของสามหลักการ: แหล่งความจริงเดียว สถานะแบบอ่านอย่างเดียว และการเปลี่ยนแปลงผ่านฟังก์ชันบริสุทธิ์ แตกต่างจาก MVC ที่โมเดลสามารถเปลี่ยนสถานะอย่างไม่สามารถคาดเดาได้ Redux รับประกันความแน่นอน: ด้วยข้อมูลนำเข้าเดียวกัน ผลลัพธ์จะเหมือนเดิมเสมอ
Redux ได้รับแรงบันดาลใจจากสถาปัตยกรรม Flux ของ Facebook และภาษา Elm ความแตกต่างหลักจาก Flux คือ Store เดียวแทนที่จะหลายตัว ใน Redux สถานะทั้งหมดของแอปพลิเคชัน — อ็อบเจกต์ อาร์เรย์ ธงการโหลด — ถูกเก็บในโครงสร้างเดียว ทำให้การดีบัก การทดสอบ และการดีบักย้อนเวลาเป็นเรื่องง่ายขึ้น นักพัฒนาสามารถบันทึก Store ทั้งหมด เล่นลำดับ Action ซ้ำ และดูว่าสถานะเปลี่ยนแปลงไปอย่างไรในแต่ละขั้นตอน
จากการสำรวจ State of JS 2025 ผู้ตอบแบบสอบถาม 68% ที่ใช้การจัดการสถานะเลือก Redux หรือ Redux Toolkit เครื่องมือนี้รองรับโดยเฟรมเวิร์กสมัยใหม่ทั้งหมด: React, React Native, Angular, Vue และแม้แต่ JavaScript แวนิลลาไร้เฟรมเวิร์ก
การไหลของข้อมูลทางเดียว คือหลักการสำคัญของ Redux ที่ข้อมูลเคลื่อนที่ในทิศทางเดียวอย่างเคร่งครัด: View → Action → Dispatch → Reducer → Store → View ไม่มีคอมโพเนนต์ใดสามารถเปลี่ยน Store โดยตรง View สมัครรับการเปลี่ยนแปลงผ่าน useSelector หรือ connect และเริ่มต้นการเปลี่ยนแปลงผ่าน dispatch
วงจรการทำงานของ Redux: ผู้ใช้คลิกปุ่ม → คอมโพเนนต์เรียก dispatch({ type: 'INCREMENT' }) → Store ส่ง Action ไปยัง Root Reducer → Reducer คำนวณสถานะใหม่ → Store แจ้งผู้สมัครรับ → View เรนเดอร์ใหม่ด้วยข้อมูลใหม่ วงจรนี้รับประกันว่าทุกการเปลี่ยนแปลงมีสาเหตุที่ชัดเจนในรูปแบบของ Action ที่เฉพาะเจาะจง
DevTools — เครื่องมือในตัวของ Redux สำหรับตรวจสอบทุก Action สถานะของ Store และเวลาดำเนินการ นักพัฒนาเห็นรายการ Action ทั้งหมดที่ถูกส่ง ความแตกต่างของสถานะ (diff) ก่อนและหลัง และสามารถย้อนกลับไปยังสถานะก่อนหน้าใดก็ได้ ทำให้การดีบักสถานะที่ซับซ้อนเร็วขึ้นหลายสิบเท่าเมื่อเทียบกับการบันทึกแบบดั้งเดิม
Store — อ็อบเจกต์ที่มีโครงสร้างสถานะทั้งหมดของแอปพลิเคชัน สร้างผ่าน configureStore (RTK) หรือ createStore Store มีสามเมธอด: getState() สำหรับอ่าน dispatch(action) สำหรับเปลี่ยนแปลง และ subscribe(listener) สำหรับสมัครรับ ใน Redux Toolkit Store มี middleware, DevTools และการรองรับ slice อยู่แล้ว
import { configureStore } from '@reduxjs/toolkit'
interface CounterState {
value: number
}
const initialState: CounterState = { value: 0 }
function counterReducer(
state = initialState,
action: { type: string }
): CounterState {
switch (action.type) {
case 'INCREMENT':
return { value: state.value + 1 }
default:
return state
}
}
const store = configureStore({ reducer: counterReducer })
store.dispatch({ type: 'INCREMENT' })
console.log(store.getState()) // { value: 1 }Action และ Action Creator — Action คืออ็อบเจกต์ที่มีฟิลด์บังคับ type (ค่าคงที่สตริง) และ payload เลือกได้ (ข้อมูล) Action Creator คือฟังก์ชันที่ส่งคืน Action ใน Redux Toolkit ใช้ createAction เพื่อสร้าง Action พร้อมการกำหนดชนิดอัตโนมัติ
Reducer — ฟังก์ชันบริสุทธิ์ที่รับสถานะปัจจุบันและ Action ส่งคืนสถานะใหม่ Reducer ต้องไม่: เปลี่ยนสถานะโดยตรง (ส่งคืนอ็อบเจกต์ใหม่) เรียก API สร้างตัวเลขสุ่ม หรือเข้าถึง Date ความไม่เปลี่ยนแปลงได้มาจากตัวดำเนินการ spread ... หรือ Immer (ในตัวของ RTK)
| ส่วนประกอบ | หน้าที่ | ข้อจำกัด |
|---|---|---|
| Store | จัดเก็บสถานะ, dispatch, subscribe | หนึ่งตัวต่อแอปพลิเคชัน |
| Action | อธิบายความตั้งใจที่จะเปลี่ยนสถานะ | ต้องมี type |
| Reducer | คำนวณสถานะใหม่ | ฟังก์ชันบริสุทธิ์ ไม่มีผลข้างเคียง |
| Dispatch | ส่ง Action ไปยัง Reducer | ซิงโครนัสโดยค่าเริ่มต้น |
| Selector | ดึงข้อมูลจาก Store | การจดจำผ่าน createSelector |
Middleware คือสายโซ่ของฟังก์ชันที่แทรกระหว่างการเรียก dispatch และช่วงเวลาที่ Action ถึง Reducer แต่ละ middleware รับ Store API และสามารถบันทึก แก้ไข หน่วงเวลา หรือยกเลิก Action ได้ Redux Thunk คือ middleware มาตรฐานสำหรับการดำเนินการแบบอะซิงโครนัส ที่อนุญาตให้ dispatch ฟังก์ชันแทนอ็อบเจกต์
import { createAsyncThunk } from '@reduxjs/toolkit'
export const fetchUser = createAsyncThunk(
'users/fetchById',
async (userId: number, { rejectWithValue }) => {
const response = await fetch(`/api/users/${userId}`)
if (!response.ok)
return rejectWithValue('Failed to fetch')
return await response.json()
}
)Middleware ยอดนิยม: Redux Thunk — สำหรับการเรียกแบบอะซิงโครนัสอย่างง่าย Redux Saga — สำหรับสถานการณ์ที่ซับซ้อนด้วยเจเนอเรเตอร์ Saga (debounce, race, คำขอแบบขนาน) Redux Observable — บนพื้นฐานของ RxJS สำหรับสตรีมแบบรีแอคทีฟ ใน Redux Toolkit middleware เชื่อมต่อผ่านพารามิเตอร์ middleware ใน configureStore
จากการสำรวจ State of JS 2025 Thunk ถูกใช้ใน 72% ของโปรเจกต์ Redux, Saga ใน 18%, Observable ใน 5% สำหรับแอปพลิเคชันส่วนใหญ่ การรวมกันของ Thunk + RTK Query ก็เพียงพอที่จะครอบคลุม 95% ของเวิร์กโฟลว์ข้อมูลแบบอะซิงโครนัส
Redux Toolkit (RTK) คือวิธีการเขียนลอจิก Redux อย่างเป็นทางการและแนะนำ เปิดตัวในปี 2019 RTK ประกอบด้วย configureStore, createSlice, createAsyncThunk และ createEntityAdapter ซึ่งลดโค้ดเทมเพลตของ Redux ลง 60-70% แทนที่จะสร้าง Action Creator, Reducer และชนิดด้วยตนเอง ใช้ createSlice เพียงตัวเดียว
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment(state) { state.value += 1 },
incrementByAmount(state, action: PayloadAction<number>) {
state.value += action.payload
}
}
})
export const { increment, incrementByAmount } = counterSlice.actions
export default counterSlice.reducerRTK Query คือโซลูชันในตัวสำหรับทำงานกับ API บนพื้นฐานของ Redux Toolkit ช่วยให้กำหนดเอนด์พอยต์แบบประกาศผ่าน createApi พร้อมการสร้างฮุคอัตโนมัติ การแคช การทำให้แท็กเป็นโมฆะ และการอัปเดตแบบมองโลกในแง่ดี RTK Query แทนที่การเขียน Thunk, Reducer และ Selector ด้วยตนเองสำหรับทุกคำขอ API
Entity Adapter — ยูทิลิตี้ createEntityAdapter สำหรับการทำให้คอลเลกชันเอนทิตีเป็นมาตรฐาน มี reducer CRUD ในตัว, selector และการเรียงลำดับสำหรับอาร์เรย์ของอ็อบเจกต์ หาก Store มีรายชื่อผู้ใช้ สินค้า หรือคำสั่งซื้อ — Entity Adapter จะลดโค้ด reducer ลง 80%
React Native Redux คือสแต็กมาตรฐานสำหรับแอปพลิเคชันมือถือใน JavaScript Redux ผสานรวมผ่าน Provider จาก react-redux ซึ่งครอบคลุมคอมโพเนนต์รากของแอปพลิเคชัน ฮุค useSelector และ useDispatch ให้คอมโพเนนต์เข้าถึงสถานะโดยไม่ต้อง props drilling Persist — redux-persist บันทึก Store ใน AsyncStorage หรือ MMKV คืนค่าสถานะหลังจากเริ่มต้นแอปพลิเคชันใหม่
Middleware สำหรับ React Native: redux-flipper สำหรับดีบักผ่าน Flipper, redux-observable สำหรับสตรีมแบบรีแอคทีฟกับไดรเวอร์เนทีฟ, react-native-mmkv สำหรับพื้นที่จัดเก็บถาวรที่รวดเร็ว ปลั๊กอินนำทาง redux-first-router เชื่อมต่อหน้าจอกับ Store ทำให้สามารถคืนค่าสถานะหน้าจอเมื่อกลับมา
ใน React Native Redux ถูกใช้ร่วมกับกลยุทธ์ network-first: แอปพยายามโหลดข้อมูลจากเซิร์ฟเวอร์ก่อน จากนั้นแคชใน Store ผ่าน RTK Query หรือ redux-persist โหมดออฟไลน์ทำได้โดยการรวม Redux + NetInfo + คิวของ Action สำหรับส่งซ้ำเมื่อการเชื่อมต่อกลับคืนมา
คำถามที่พบบ่อย
Redux เป็นโซลูชันเต็มรูปแบบที่มี Store, DevTools, Middleware และสถานะที่ไม่เปลี่ยนแปลง Context API เป็นกลไกในตัวของ React สำหรับส่งข้อมูลโดยไม่ต้อง props drilling Context เหมาะสำหรับธีมสากลและการแปลภาษา ในขณะที่ Redux เหมาะสำหรับสถานะที่ซับซ้อนพร้อมการดำเนินการแบบอะซิงโครนัส การแคช และการดีบัก ในแอปพลิเคชันขนาดใหญ่ Context ทำให้เกิดการเรนเดอร์ซ้ำโดยไม่จำเป็น ในขณะที่ Redux พร้อม selector แก้ปัญหานี้
Immer คือไลบรารีสำหรับการจัดการสถานะที่ไม่เปลี่ยนแปลง ซึ่งอยู่ใน Redux Toolkit Immer ช่วยให้เขียน reducer ราวกับว่ากำลังเปลี่ยนสถานะโดยตรง: state.value += 1 เบื้องหลัง Immer สร้างอ็อบเจกต์พร็อกซี (draft) ติดตามการเปลี่ยนแปลงและส่งคืนอ็อบเจกต์ที่ไม่เปลี่ยนแปลงใหม่ ซึ่งลดปริมาณโค้ด reducer ลง 50% และกำจัดการเปลี่ยนแปลงโดยไม่ตั้งใจ
ลอจิก Redux ถูกทดสอบแบบแยกส่วน: Reducer — ฟังก์ชันบริสุทธิ์ เพียงเรียกใช้ด้วย Action ต่างๆ และตรวจสอบผลลัพธ์ Action Creator — ตรวจสอบอ็อบเจกต์ที่ส่งคืน Thunk — จำลอง API เรียก dispatch และตรวจสอบว่า Action ใดถูกส่ง คอมโพเนนต์ที่ใช้ useSelector — ใช้ Provider กับ Store ทดสอบในเรนเดอเรอร์ Redux DevTools ช่วยเขียนทดสอบโดยเล่นลำดับ Action จากเซสชันจริงซ้ำ
useState เพียงพอสำหรับสถานะท้องถิ่นของคอมโพเนนต์เดียว: ข้อความในฟิลด์ เปิด/ปิด modal Redux จำเป็นเมื่อสถานะถูกใช้ร่วมกันระหว่างหลายหน้าจอ ต้องการการซิงค์แบบอะซิงโครนัส (ข้อมูลจากเซิร์ฟเวอร์) ต้องคงอยู่ระหว่างการเริ่มต้นแอปใหม่ (persist) หรือต้องการการดีบักย้อนเวลา สำหรับแอปพลิเคชันขนาดเล็ก Redux มากเกินไป — ให้ใช้ Context + useReducer แทน
Normalizr คือไลบรารีสำหรับทำให้ข้อมูลซ้อนกันเป็นโครงสร้าง Store แบบเรียบ แทนที่จะจัดเก็บอ็อบเจกต์ลึกอย่าง user.posts[0].comments การทำให้เป็นมาตรฐานสร้างพจนานุกรม: entities.users, entities.posts, entities.comments พร้อมการอ้างอิงตาม ID ซึ่งช่วยลดความซับซ้อนในการอัปเดตเอนทิตีเดียวในทุกที่และเร่ง selector Redux Toolkit แนะนำข้อมูลที่ทำให้เป็นมาตรฐานสำหรับโมเดลที่ซับซ้อน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม