15分鐘學會在React中使用Redux

React作為一套優(yōu)秀的前端框架,為我們提供了一套十分優(yōu)秀的頁面構建方法和思想。可是,React還只是一套視圖構建框架,在軟件設計模塊里面還只是MVC的View層,涉及數據模型時需要一些其他框架的輔助。其中,最著名的莫過于Redux了。既然是結合React使用Redux,那么前端大爺假設你已經使用過React框架,對React有一定的了解了,并且大概知道action, reducer, dispatch的關系,否則請先移步其他書籍文檔,因為無論如何15分鐘內不可能從不會走到學會跑。

-----------------------------------分割線 0 分鐘---------------------------------

先解釋原理

首先,React組件有state, props沒錯吧。state是內部的狀態(tài),props是父組件傳進來的屬性,state, props變化了要觸發(fā)react diff并且調用render方法更新組件,同意吧。好,就是這么簡單的react基本原理,告訴我們除了用戶交互導致內部state變化外,數據流是從父組件通過props流向子組件導致子組件更新。這就是React的單向數據流:

            自頂向下單向數據流!
            
            自頂向下單向數據流!
            
            自頂向下單向數據流!

重要的事情說三遍。

假設我們的app入口是這樣的:

ReactDOM.render(
    <App />
    document.getElementById('root')
);

這個App也是一個React組件,它是我們的項目中居于最頂層的父組件。如果我們有某個組件,他能夠提供數據源,而又居于App之上,那么數據就可以源源不斷的從它往下流到App以及各級子孫節(jié)點上去。所以Redux給我們提供了Provider:


import { Provider } from 'react-redux'


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


-----------------------------------分割線 5 分鐘---------------------------------

Provider接受一個屬性store,這就是我們全局的數據store。我們要根據reducer函數來創(chuàng)建它。

import { createStore } from 'redux'
import { combineReducers } from 'redux'


//reducer函數接受兩個參數,state和action,state帶默認的初始值
function reducer1(state = [], action) {
    switch(action.type) {
        case 'add':
            return [...state, 'apple is very delicious'];  // 這里一定要返回一個新的數組,而不能寫成state.push('apple is very delicious1');
            
        default  :
            return state;  
    }
}

//reducer當然可以定義多個,不同的reducer對應著不同的state對象,上面的reducer1操作一個數組對象,這個reducer2操作一個Number類型state
function reducer2(state = 0, action) {
    switch(action.type) {
        case 'increase' :
            ++state;
            return state;
        default:
            return state;    
    }
}

const reducer = combineReducers({
    reducer1,
    reducer2
  })

var store = createStore(reducer);   

store生成了,隨時可以通過store.getState()獲得當前store的值。初始狀態(tài)下調用getState()獲得的返回值是

{reducer1: [], reducer2: 0}。

看,reducer函數的名字對應著store里面state的名字。

為了幫助初學者學習,可以添加以下語句,監(jiān)聽每一次dispatch操作后store的狀態(tài):

store.subscribe(()=>{
    console.log(store.getState());
})

-----------------------------------分割線 10 分鐘---------------------------------

現(xiàn)在我們有了最高級別的Provider,并定義好了reducers, 傳入了store。接下來我們該考慮子組件了。子組件長什么樣,要靠父組件給的props決定,可是數據都在最高級別的provider store里面,怎么樣把store里面的數據拿出來作為props給子組件呢?。。??

react-redux給我們提供了魔法黑科技:mapStateToProps和mapDispatchToProps。

顧名思義,把state和dispatch從store里面拿出來,作為props傳給子組件!

const mapStateToProps = state => {
  return {
    state1: state.reducer1
  }
}

const mapDispatchToProps = dispatch => {
  return {
    add: () => {
      dispatch({
        type:'add'
      })
    }
  }
}

class AppView extends Component {

  render() {
    const list = this.props.state1.map(v=>{
      return (<p className="App-intro">{v}</p>)
    })
    return (
      <div className="App">
        <p>{list.length}</p>
        {
          list
        }
        
        <button onClick={()=>this.props.add()}>add</button>
      </div>
    );
  }
}


const App = connect(
  mapStateToProps,
  mapDispatchToProps
)(AppView)
export default App;

看到了嗎,經過mapStateToProps和mapDispatchToProps處理后,我們直接在子組件AppView里面使用this.props.state1就可以拿到store里面的數據,直接使用this.props.add就可以dispatch相應的action。store變化后視圖的更新是自動的,無需手工干預。

源代碼見:https://github.com/myairforce1/simpleReduxDemo

看到這你是不是對在React中使用Redux有點感覺了呢?請原諒本文使用了一個極為簡陋的例子。本著老少咸宜,童叟無欺的初衷,我盡量搬上來一個功能少,但是好理解的例子。如果的確幫助到您,請留下您對本文的喜愛。

-----------------------------------分割線 15 分鐘---------------------------------
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容