整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ
終究都要學 React 何不現在學呢? - React 進階 - useReducer - (15)
前言
接著我們要來認識一個很特別的東西,也就是 useReducer,而 useReducer 可以說是 useState 的進階版,因為 useReducer 可以讓我們在處理複雜的狀態時,可以更好的管理狀態,而不是像 useState 一樣,只能用一個變數來管理狀態。
useReducer
前言我們有提到 useReducer 是 useState 的進階版,簡單來講呢…useReducer 非常接近 Redux 寫法(一套用於資料狀態管理的函式庫,類似於 Vue 的 Vuex、Pinia,不了解這些是什麼也沒關係,只是稍微提到而已)。
那麼接著就讓我們先看一下 useReducer 的語法吧!
1 | |
看起來與 useState 很像,但是 useReducer 有三個參數,而 useState 只有兩個參數
1 | |
可以明顯看出這兩個 Hook 是有差異的(廢話)。
接著讓我們看一下 useReducer 中的參數,也就是 reducer、initialState、init 這三個參數,這邊先撇除 init 這個參數,因為這個參數是可選的,所以我們只需要著重於先看 reducer 跟 initialState 這兩個參數。
這邊先題外話一下,其實在 React 官方文件有提到一句話
useState 的替代方案。接受一個 (state, action) => newState 的 reducer,然後回傳現在的 state 以及其配套的 dispatch 方法。
稍微有一點難懂,但其實重點就是在講 useReducer 就是另一個 useState (也就是前面講的變體),因此 useReducer 再回傳時其實也是回傳一個陣列,而這個陣列中的第一個元素就是 state,而第二個元素就是 dispatch。
那麼實際上該怎麼使用 useReducer 呢?讓我們來看一下範例吧!
首先先宣告一個初始化的狀態 State
1 | |
請注意通常初始的狀態會是一個物件。
接下來是宣告一個叫做 reducer 的函式,請注意 reducer 會傳入兩個參數,分別是 state 與 action
1 | |
而這個 reducer 函式裡面通常會使用到 switch 語法,並且是使用 action 參數當作判斷依據,有趣的是 action 會有一個屬性是 type,我們會使用該屬性當作判斷,所以接著裡面我們先寫一個 default 並寫回傳一個物件
1 | |
接下來呢?讓我們回到 App 元件內,只需要在裡面使用 useReducer 並傳入 reducer 跟 initialState 這兩個參數,就可以取得 state 跟 dispatch 這兩個變數囉~
1 | |
接下來畫面只需要這樣子撰寫就可以輕鬆渲染出 count 了!
1 | |
我們可以看到畫面已經正常且正確的呈現,但實際上來講目前只是讓程式碼正常運作而已,但還沒真正開始操作 state 跟 dispatch,所以接下來我們就來操作一下 state 跟 dispatch。
接下來為了能夠操作 useReducer 生出來的 state 跟 dispatch,因此畫面上增加兩個按鈕,然後我們會透過 dispatch 修改來 count。
請注意! dispatch 會是傳入一個物件,而屬性會是 type(主要是搭配前面寫的 switch),因此 App 元件目前如下
1 | |
目前來講你點擊畫面是不會有任何反應的,因為前面 reducer 函式我們並沒有撰寫完成。
那麼我們透過 dispatch 傳入一個物件,並且裡面有一個 type,因此 reducer 的 action 就可以取出 type,此時就可以透過這個 type 去做一些操作,例如減少 count 或是增加 count 等行為,但這邊要注意回傳時是回傳一個物件,而這個物件裡面的 count 就是我們要做的一些操作與修改
1 | |
目前為止,你的 useReducer 就已經可以正常操作了。
那麼 useReducer 跟 Vuex、Redux 有什麼不同呢?簡單來講其實 useReducer 是 React 本身所提供的一個 Hook,請注意是「本身」,代表著你不需要額外安裝就可以直接使用的一個功能,但是如果是 Vuex 跟 Redux 的話,則是框架之外所提供的狀態管理庫,因此你是必須額外安裝的。
基本上如果你的專案並沒有到非常複雜的話,其實是可以單純使用 useReducer 的,而 useReducer 本身就是一個簡單版的 Redux,但不代表可以完全取代 Redux,只是你可以透過 useReducer + useContext 來製作出簡易版的 Redux 來使用
1 | |
雖然可以使用 useReducer + useContext 製作出簡易版的 Redux,但終究還是與真正的 Redux 有些差異,因此如果你的專案需要使用 Redux 的話,那麼你還是必須額外安裝 Redux 來使用的唷。
後記
本文將會同步更新到我的部落格
整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ