1. 程式人生 > >在react專案中使用redux-thunk,react-redux,redux;使用總結

在react專案中使用redux-thunk,react-redux,redux;使用總結

先看是什麼,再看怎麼用:

redux-thunk是一個redux的中介軟體,用來處理redux中的複雜邏輯,比如非同步請求;

redux-thunk中介軟體可以讓action建立函式先不返回一個action物件,而是返回一個函式;

 

react-redux相當於一個適配react的一個redux外掛;redux本身可以在任何專案中使用,react-redux帶來了更適合react的方法;

 

而redux就是來管理資料的一個倉庫了。

核心概念是使用store來作為一個數據倉庫,所有元件都來通過資料來渲染檢視,react提供了資料到檢視的實時更新,這也就是react框架的命名來源吧;

redux中幾個關鍵詞;actionType,actionCreators,store,reducer: 這也是專案中劃分檔案的方式,將redux中每個功能劃分成單獨的檔案來管理,

使用redux流程,腦中要時時刻刻記住一張圖如下:

我們將所有需要管理的資料需要交給redux來管理,redux需要首先定義預設state放在reducers之中,而一般情況下元件會通過派發(dispatch)一個action來從store中獲取資料,store中儲存資料的地方是reducer.js;所以一般情況下會在reducer中return一個newState出來給store 而在元件中獲取store的資料的方法就需要訂閱(subscribe)store 這樣元件的state就會改變;

一般情況下的store資料夾裡分為reducer.js   index.js   constants.js(或者是actionType.js) 以及actionCreators.js  

首先元件要獲取資料,會先建立一個action,這個action是一個物件,包含action的型別(就是actionType)和值 然後store去派發這個action,store接受到action之後會交給reducer.js來處理,這裡存放了預設資料和處理之後的資料,reducer處理好資料之後,返回一個新的state給store;  然後元件需要獲取這個新的state,一般情況是通過setState來獲取函式store; 設定當前元件的state; ;this.setState(store.getState())

 

而react-redux的作用是提供了 Provider元件來讓所有元件共享所有的狀態(官話:Provider提供的是一個頂層容器的作用);如下程式碼中 store作為一個屬性來給到provider  所有的元件都可以共享這個狀態,並且react-redux提供了connect 方法來連線mapStateToProps 、mapDispatchToProps 和元件

connect常見用法如下

const mapStateToProps = (state) => {
    return{
        focused: state.getIn(['header','focused']),
        //從header 總的reducer裡面找focus的值
        //focused: state.get('header').get('focused')
        list:state.getIn(['header','list']),
        page:state.getIn(['header','page']),
        mouseIn: state.getIn(['header','mouseIn']),
        totalPage:state.getIn(['header','totalPage'])
    }
}
const mapDispatchToProps = (dispatch) => {
return{
handleInputFocus(list){
//console.log(list)
if(list.size === 0){
dispatch(actionCreators.getList())
}
dispatch(actionCreators.input_Focus())

},
handleInputBlur(){
dispatch(actionCreators.input_Blur())
},
handleMouseEnter(){
dispatch(actionCreators.mouseEnter())
},
handleMouseLeave(){
dispatch(actionCreators.mouseLeave())
},
handleChangePage(page,totalPage){
console.log(page,totalPage)
if(page<totalPage){
dispatch(actionCreators.ChangePage(page+1))
}else{
dispatch(actionCreators.ChangePage(1))
}

}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(Header);  //連線Header元件和mapStateToProps,mapDispatchToProps

  

 
 <Provider store={store}>
          <div>
            <Globalstyle/>
            <Header/>
              <BrowserRouter>
                  <div>
                    <Route path='/' exact redirect='/home' component={Home}/>
                    <Route path='/detail' component={Detail}/>
                  </div>
              </BrowserRouter>
            <Globalstyleicon/>
          </div>
      </Provider>

  

 

通常情況下,我們的專案可能會有龐大的資料,所以一般情況下會將store單獨拆分到每個元件之中,這個時候就需要我們來使用combineReducers 來連線所有的狀態;

import {combineReducers} from 'redux-immutable'
通常情況下總的reduce程式碼如下
import {combineReducers} from 'redux-immutable'  //讓生成的資料是immutable資料內容
import {reducer as headerReducer} from '../common/header/store'   //從header元件的reducer中引入reducer來結合

const reducer = combineReducers({
    header:headerReducer
})
export default reducer

  同時,我們的state資料不能隨便改變,這個時候就需要引入immutable來對資料進行管理(某個部落格這樣寫的:

JavaScript 中的物件一般是可變的(Mutable),因為使用了引用賦值,新的物件簡單的引用了原始物件,改變新的物件將影響到原始物件。如 foo={a: 1}; bar=foo; bar.a=2 你會發現此時 foo.a 也被改成了 2。雖然這樣做可以節約記憶體,但當應用複雜後,這就造成了非常大的隱患,Mutable 帶來的優點變得得不償失。為了解決這個問題,一般的做法是使用 shallowCopy(淺拷貝)或 deepCopy(深拷貝)來避免被修改,但這樣做造成了 CPU 和記憶體的浪費。

 

immutable中常用的方法:

1:fromJS  把一個普通物件改變成一個immutable物件

2:set  immutable物件的set方法,會結合之前immutable物件的值和設定的值,返回一個新的物件  使用如下: state.set('focused',true);

3:get :  get() 、 getIn()  可以用來獲取資料 如下使用:  state.getIn(['header','list'])  等價於state.get('header').get('focused')

4:merge(淺合併,新資料與舊資料對比,舊資料中不存在的屬性直接新增,就資料中已存在的屬性用新資料中的覆蓋)  

  merge使用如下:

 state.merge({
list:action.data,
totalPage:action.totalPage
})


我的程式碼倉庫:https://github.com/qiaoqiao10001