/React, React Redux

React | React 與他的快樂小夥伴 Redux-基礎教學

剛開始接觸 React 時就聽過 Redux ,雖然 ReduxReact 並不是必要的,但既然這是個趨勢,相信也值得花時間好好了解。

在使用後,也能感受到 Redux 對專案帶來的好處:

  1. 讓組件管理 state 更方便,且確保整個專案的資料都來自同一個地方。
  2. 開發時能讓畫面及資料端分離,有關畫面的就修改 Reactcomponent ,資料的部分就完全交給 Redux ,每個人各司其職、分工合作。
  3. 承上點,若是單人作業,也許會認為:「那我一個人,還有需要分開寫嗎?太麻煩了吧!」,不過就是因為一個人,將來維護時,如果發現問題就更不需要再花費時間,讓自己漫遊在一堆 componentfetchajax 的程式中尋找問題在哪裡,對吧?

既然 ReactRedux 兩者間可以這麼相處融洽,那不如就開始試試吧!


Redux 基本用法

在講解兩者如何配合前,還是得先了解 Redux 的運作模式,九把刀說過:「慢慢來,比較快。」,所以一步一步來走吧!

創建 Reducer

ReducerRedux 中是用來保管 state ,以及在接收到不同的 action 指令時該對 state 做什麼動作的函數。

首先要為該 Reducer 設計它所管理的 state 架構:

const initState = {
    name: 'Jack',
}

雖然在 Reducer 中也可以改變 state 的架構,但在 initState 中將資料架構清楚列出,還能讓接手的人或是兩個禮拜後的自己,一看就能知道這個 Reducer 保管了哪些資料。

現在有了初始資料,就可以使用它建立一個 Reducer

const reducer = (state = initState, action) => {
    switch (action.type){
        default:
            return state 
    }
}

每一個 Reducer 都會有兩個參數,第一個參數會將初始的資料狀態 initState 交由 Reducer 保管,第二個參數會傳入現在 reducer 要對 state 做什麼動作的指令及額外的參數,這些在後幾篇會再講解,所以在還沒有任何 action 指令描述的 Reducer 內,預設回傳了它所保管的 state ,在這裡就是上方的 initState

創建 store

創建 Reducer 後,還得將它交由 storestore 的工作就是在應用程式中負責整合所有的 Reducer

創建前,得先從 reduximport 進負責創建 store 的函式 createStore ,並將 Reducer 傳入以創建一個 store

import { createStore } from 'redux'

const store = createStore(reducer)

//可使用 store 的內建函式 getState() 確認目前 store 內所保管的資料console.log(store.getState())  // {name: 'Jack'}

需要注意的是,每個專案都應該只能有一個 store 存在,若是有許多不同類型的資料,則是以 Reducer 區分,最後將多個 Reducer 打包成一個後,再創建 store ,這部分的使用方法,在日後的文章也會解說。

store 產生後, Redux 的前置準備部分就告一段落,接下來說明 Reactcomponent 該如何從 Reduxstore 中取到資料。


React-Redux 登場

React 需透過幾個步驟才能將 Redux 所保管的資料流向 component 。首先像需求單一樣,定義要從 store 中取得的資料,並將 component 與該需求單做連結,之後再利用 Providerstore 根據需求單將資料流進 component 中。以下開始實現這些步驟:

填寫需求單

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

上方創建一個函式 mapStateToProps ,並在該函式內部定義需要哪些資料,它有個參數 state ,在連接時 Redux 會將 store 傳進這個位置,因此上方指定了 store 中保管的 name 資料,並以 namekeyprops 流進 component 中。

創建組件

import React from 'react'

class ConnectTitle extends React.Component {
    render(){
        return <h1>Hello!{this.props.name}</h1>
    }
}

因為待會會與 mapStateToProp 進行連結,所以在組件名稱前個人多註記了 Connect ,代表該 component 內含有從 store 中取的資料,而上方的 {this.props.name} 正是需求單上指定的名稱也就是 name

連結 componentmapStateToProps

在這個步驟前得先從 react-reduximportconnect ,再進行連結:

import { connect } from 'react-redux'

const Title = connect(mapStateToProps)(ConnectTitle)

透過 connect 分別將 mapStateToPropsConnectTitle 送進處理,會得到一個新的 component ,在上方使用 Title 接收結果。

設置 Provider

Providerreact-redux 中的組件,它會接收上方在 Redux 中創建的 store ,並根據和 component 綁在一起的需求單 mapStateToProps 上要求的資料從 store 中取出,再透過 props 流向 component

import { connect, Provider } from 'react-redux'
import ReactDOM from 'react-dom'

ReactDOM.render(<Provider store={store}>
                    <Title />
                </Provider>,
                document.getElementById('root'))

上方的 Provider 在最外層,並為他指定了 store

注意!不論是多麼大的專案, Provider 永遠都在最外層,也永遠都只有一個,為了保持資料來源都是從 Provider 流進內部的 component ,這也是為什麼每個專案中 store 應該都只能有一個。

接著運行應用程式,確認最後輸出的結果:



本文是關於 ReactRedux 最基本的使用方式,筆者剛學的時候真的覺得很困難,也有很多觀念一直理不清楚,包括上面提到的 store 為什麼只能有一個,不過還好在三番兩次的實際操作後,不只更了解,而且像開頭說的,體會到使用 Redux 的好處後,對他就更愛不釋手,希望本篇文章能夠帶給和當初的我一樣,為學習 Redux 困擾的大家。

如果文章中有任何問題,或是不理解的地方,都歡迎留言告訴我,謝謝大家!