React Redux with Functional Components
本文介紹 React Redux 於 Functional Components 的使用。
useSelector hook
A hook to access the redux store's state, and manage the subscription behind the scenes.
useSelector
會監控 Redux 特定狀態的更動,有點類似 Vuex 中 computed
計算屬性的感覺。
1import { useSelector } from 'react-redux'; 2 3const Counter = () => { 4 // 取出 store 裡面特定的 state,只取得需要的 state! 5 const counter = useSelector((state) => state.counter); 6 7 return ( 8 <main> 9 <div>{counter}</div> 10 </main> 11 ); 12}; 13 14export default Counter; 15
當 Redux Store 更新時,使用 counter
的 Component 也會一起被更新(重新評估、執行),因為這樣才能確保接收 Redux 最新的 state
喔。
useDispatch hook
A hook to access the redux
dispatch
function.
useDispatch
提供 dispatch 函式:const dispatch = useDispatch()
。
1import { useDispatch } from 'react-redux'; 2 3const Counter = () => { 4 const dispatch = useDispatch(); 5 6 const incrementHandler = () => { 7 dispatch({ type: 'INCREMENT' }); 8 }; 9 10 const decrementHandler = () => { 11 dispatch({ type: 'DECREMENT' }); 12 }; 13 14 return ( 15 <main> 16 <button onClick={incrementHandler}>Increment</button> 17 <button onClick={decrementHandler}>Decrement</button> 18 </main> 19 ); 20}; 21 22export default Counter; 23
給 Actions 物件加上更多 Payloads
瞭解 Redux 基本的使用後,我們繼續往下看一些比較深入而且實用的功能吧!
當我們 Dispatch 一個 Action 物件時,Payload 裡面除了 type
我們還可以放更多內容,像是定義 amount
,讓按鈕可以一次加上指定的數量。
1// Counter Component 2const Counter = () => { 3 const increaseHandler = () => { 4 dispatch({ type: 'INCREASE', amount: 5 }); 5 }; 6 // return jsx... 7}; 8 9// Redux Reducer Function 10const counterReducer = (state = { counter: 0 }, action) => { 11 if (action.type === 'INCREASE') { 12 return { counter: state.counter + action.amount }; 13 } 14}; 15
如果有多個 State 記得一起更新
進行 Dispatch Action 更新 State 物件時,就算有些 State 我們在 Action 中不會去改動到,但還是需要把它們寫進 return
的物件裡,因為這個 return
的物件是會取代掉原本的整個 State 物件的。
- 重點一:
return
的 State 不是合併,是整個「覆寫」! - 重點二:千萬不要直接改變 (Mutate) 現有的狀態,也就是不能直接對 State 做改變,正確的做法是在進行操作後,再去
return
整個新的 State 物件。
1if (action.type === 'INCREASE') { 2 // Never mutate state!!! 3 // state.counter++; 4 // return state; 5 return { 6 counter: state.counter + action.amount, 7 showCounter: state.showCounter, // 不更動 8 }; 9} 10 11if (action.type === 'TOGGLE') { 12 return { 13 counter: state.counter, // 不更動 14 showCounter: !state.showCounter, 15 }; 16} 17
回顧
看完這篇文章,我們到底有什麼收穫呢?藉由本文可以理解到…
- useSelector hook
- useDispatch hook