iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0
Modern Web

以 React 為主的那些前端事系列 第 16

Day 16 - 用 useReducer 取代 Redux !?

  • 分享至 

  • xImage
  •  

如果有錯誤,歡迎留言指教~ Q_Q

useReducer 看起來跟 Redux 的 reducer 很像欸!那他能夠取代 Redux 嗎?

先回憶一下 Redux

Redux 是一個用來管理 State 的 library

Flux、Vuex、MobX 等等也都是常見管理 state 的library

現在還有個 XState !

當狀態邏輯在畫面裡越長越大時,就該把他們拆開了!

  • Component → 處理UI畫面
  • Redux → 處理狀態資料

這樣維護和重用性也都能夠提高,未來的自己要看的時候,也清楚很多

Redux 用法

Redux 有 Reducer、Store、provider

  • Reducer → 保存 state,當接收到 action 時,要對 state 做動作的函數。可以區分很多類型~ 再給 Store 統一管理
  • Store → 管理 Reducer 的地方,負責整合所有的 Reducer,一個專案只有一個,唯一
  • provider → 在最外層,且只有唯一一個:接收 store 給的資料後,再傳遞給內部的 component
  1. 建立 action 描述動作

一個描述要做什麼事情的 object,store.dispatch() 把資訊傳遞到 store

  1. 建立 state 儲存資料

一個簡單的 object,且盡量讓資料和 UI 狀態分離。

const initialState = {
  id: '',
  text: action.text,
  completed: false
}
  1. 建立 Reducer,接收不同的 action,管理 state

reducer 是一個 pure function,它接收先前的 state 和一個 action,然後回傳下一個 state。

(previousState, action) => newState

action 會傳入現在 reducer 要對 state 做什麼動作的指令及額外的參數

action 可以區分很多類型~ 再給 Store 統一管理

const reducer = (state = initState, action) => {
    switch (action.type) {
        case 'ADD_TODO':
          return [
            ...state,
            {
              id: action.id,
              text: action.text,
              completed: false
            }
          ]
        case 'TOGGLE_TODO':
          return state.map(todo =>
            (todo.id === action.id)
              ? {...todo, completed: !todo.completed}
              : todo
          )
        default:
          return state
      }
}

在 default case 回傳先前的 state。針對任何未知的 action 回傳先前的 state

4.建立 store,並傳入 Reducer

管理 Reducer 的地方,負責整合所有的 Reducer,一個專案只有一個,唯一!

使用 createStore 建立 store 並把 reducer 傳進去

import { createStore } from 'redux'

const store = createStore(reducer)

  1. provider

在最外層,且只有唯一一個:接收 store 給的資料後,再傳遞給內部的 component

用 Provider 將 store 根據需求將資料流進 component

  1. react-redux

用 connect 把 指定好的資料 state 和 component 連結起來

import { connect } from 'react-redux'

const mapStateToProps = state => ({
    name: state.name
})

// 把資料和元件 connent 後,就會得到一個新的 組件
const Title = connect(mapStateToProps)(ConnectTitle)

你永遠不應該在 reducer 裡面做這些事:

  1. 不改變 state
  2. 不執行會有 side effect 的動作,像是呼叫 API 和 routing 轉換。
  3. 不呼叫不是 pure 的 function,像是 Date.now() 或是 Math.random()。

484 就是跟 useReducer 很像呢~

那 useReducer 能不能取代 Redux?

不行!雖然很像,一樣擁有 Action/Reducer/dispatch......

useReducer 並不像 redux 擁有 global 的 store


上一篇
Day 15 - 用 useReducer 取代 useState !?
下一篇
Day 17 - useReducer + useContext = Redux?
系列文
以 React 為主的那些前端事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言