React和Redux手動鏈接過程
1.新建store(倉庫)
import {createStore} from 'redux'
const store = createStore(reducer)//通過傳入reducer建立store
2.以組件屬性形式傳遞給組件裏
function render(){
ReactDom.render(<App store={store}/>)
}
render()
3.使用store的subscribe函數訂閱render()
store.subscribe(render)
4.組件內部通過props獲取store
const store= this.props.store
5.補充一個reducer和action creator的例子
//reducer
export function documents(state=initState,action){
switch(action.type){
case GET_DOCUMENT_SUCCESS:
return {...state,documents:action.documents}
case ERROR_MSG:
return {...state,msg:action.msg}
default:
return state;
}
}
//action creator ==>create reducer action 只要提交action reducer就會執行
export function getDocumentInfo({type}){
//返回函數需要使用thunk
return dispatch=>{
axios.get('asd',{type})
.then(
res=>{
console.log(res);
if(res.state===200){
dispatch(getInfoSuccess(res.data.documents))
}else{
dispatch(errorMsg(res.msg))
}
}
)
.catch(function (error) {
console.log(error);
});
}
更進一步,Redux和React更優雅的結合
1. Redux處理異步使用redux-thunk插件
2. npm install redux-devtools-extension 並且開啓
3. 使用react-redux優雅的鏈接react和redux
1.Redux默認只處理同步,異步任務需要react-thunk中間件
- npm install redux-thunk --save
- 使用applyMiddleware開啓thunk中間件
- Action由返回對象增加可以返回函數,這時使用dispatch提交action
import thunk from 'redux-thunk';
import {createStore,applyMiddleware} from 'redux';
const store = createStore(reducers,applyMiddleware(thunk))
2.調試工具
1.Chrome搜索redux插件安裝
2.新建store的時候判斷window.devToolsExtension
3.使用compose結合thunk和window.devToolsExtension
4.通過調試窗redux選項卡實時看到state
import {createStore,applyMiddleware,compose} from 'redux';
const store = createStore(reducers,compose(
applyMiddleware(thunk),
window.devToolsExtension?window.devToolsExtension():f=>f
))
3.使用react-redux
1.npm install react-redux --save
2.忘記subscribe,記住reducer,action和dispatch即可
3.React-redux 提供Provider和connect兩個接口來鏈接
1.Provider組件在應用最外層,傳入store即可,只用一次
import { Provider } from "react-redux";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
2.Connect負責從外部獲取組件需要的參數(Connect可以用裝飾器來寫)
connect方法
connenct並不會改變它“連接”的組件,而是提供一個經過包裹的connect組件。 conenct接受4個參數,分別是mapStateToProps,mapDispatchToProps,mergeProps,options(使用時注意參數位置順序)。
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
這裏只介紹兩個必須參數
mapStateToProps(state, ownProps) 方法允許我們將store中的數據作爲props綁定到組件中,只要store更新了就會調用mapStateToProps方法,mapStateToProps返回的結果必須是object對象,該對象中的值將會更新到組件中,例子:
const mapStateToProps = (state) => {
return ({
count: state.counter.count
})
}
mapDispatchToProps(dispatch, [ownProps]) 第二個參數允許我們將action作爲props綁定到組件中,mapDispatchToProps希望你返回包含對應action的object對象,例如:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
increase: (...args) => dispatch(actions.increase(...args)),
decrease: (...args) => dispatch(actions.decrease(...args))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(yourComponent)
實例:
Class App extends React.Component{
}
const mapStateToProps(state){
return {num:state}
}
const mapDispatchToProps={yourActionCreators}
App = connect(mapStateToProps,mapDispatchToProps)(App)
export default App
使用裝飾器優化connect代碼
1.npm run eject彈出個性化配飾(針對create-react-app)
2.npm install babel-plugin-transform-decorators-legacy --save
3.package.json 裏babel加上plugins配置
3.babel加上plugins配置
"babel": {
"presets": [
"react-app"
],
"plugins":["transform-decorators-legacy"]
},
改變寫法爲
```
const mapStateToProps(state){return {num:state}}
const mapDispatchToProps={yourActionCreators}
@connect(mapStateToProps,mapDispatchToProps)
Class App extends React.Component{
}
export default App
“`