先看是什么,再看怎么用:
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