先來說講redux是什麼吧,咱們一般在react開發中都會這麼說說,引入redux處理數據流,可是這裏講的redux已是通過二次封裝的內容react-redux了,而他的原始形態纔是redux,是一個不依賴react就能進行數據流處理的組件。而redux的又是脫胎於flux思想。flux是由facebook工程師提出的一種解決方案,他的名字是拉丁語的flow,主要是爲了解決MVC架構存在的問題。他的核心思想是數據和邏輯永遠單向進行流動。 講到這裏,咱們先描述下flux當時想要解決的問題(笑,也就是大名鼎鼎的MVC結構。react
首先,咱們先考慮下傳統的react的數據處理的組件結構來實現一個博客的論壇評論app 論壇評論的app主要包含兩個功能:json
咱們嘗試着去書寫一個評論展現區的方案,專門用一個model組件來處理數據,再使用一個純函數組件來進行業務邏輯組件的展現 代碼以下:redux
import React,{Component,PropTypes}from 'react';
class CommentListContainer extends Component{
constructor(props){
super(props)
this.state={loading:true,error:'',value:''}
}
componentDidMount(){
this.props.promise.then(res=>res.json())
.then(value=>this.setState({loading:false,value}))
.catch(error=>this.setState({loading:false,error}))
}
render(){
const{loading,error,value}=this.state
if(loading){
return <span>loading....</span>
} else if(error.length!==0){
return <span>Error:{error}</span>
}else{
return(
<CommentList comments={list}
)
}
}
}
function CommentList({comments}){
return(
<ul>
{
comments.map((v,i)=>(
<li key={v.id}>{v.text}</li>
))
}
</ul>
)
}
複製代碼
以上是咱們在不使用redux的時候進行的react組件方案api
這樣子看起來是和數據解耦了,可是實際上數據仍是在對應的組件內部進行保存,並不算完全的解耦數組
而以上的模型就是咱們咱們在MVC模型中講述的Model和View,至於爲何沒有Controller,由於對於純函數組件來講,他不須要感知他作了什麼內容,只須要知道用戶的操做須要激發一個更改,因此若是有數據操做,也會放在Model中進行代碼的書寫,而View僅僅進行一個操做的動做 MVC Model負責同步數據,校驗數據 View負責可視化,Controller負責鏈接View和Controller, MVC是上世紀80年代被提出的概念,直到2005年,他的問題被放大 那麼MVC的問題是什麼呢,下面用一張流程圖來展現 promise
講完了mvc的解決方案來說講flux的解決方案,用一張圖表示剛剛說的核心思想,數據和邏輯永遠單向流動瀏覽器
運用方式想必你們都很熟悉了,經過connect鏈接store,dispatch分發action來觸發的機制 這裏注重給你們介紹幾種比較實用的中間件bash
handleChangeName(e){
this.setState({
name:e.target.value
})
}
handleChangeAddress(e){
this.setState({
address:e.target.value
})
}
render(){
const {name,address}=this.state
return(
<form>
<input name="name" value={name} onChange={this.handleChangeName} />
<input name="address" value={address} onChange={this.handleChangeAddress} />
</form>
)
}
複製代碼
能夠看得出來,這個change事件的代碼很是容易,並且大部分處理邏輯相似,這個時候用中間件能夠怎麼寫antd
import {createForm } from 'redux-form-utils'
@createForm({
form:'my-form',
fields:['name','address']
})
class Form extends Component{
render(){
const {name,address}=this.props.fields;
return(
<form className='form'>
<Input name='name' {...name} />
<Input name='address' {...address} />
</form>
)
}
}
複製代碼
經過deractor+高階組件的寫法,內部封裝了有關於form表單的處理來實現對代碼的簡寫 用過antd的同窗確定發現了,這種寫法其實就是antd的form表單的寫法. redux-form-utils除了createForm還有個bindRedux,具體做用是在若是表單的數據是用來整個存放在redux中的表單數據架構
function createThunkMiddleware(extraArgument){
return({dispatch,getState})=>next=>action{
if(typeof action==='function'){
return action(dispatch,getstate,extraArgument)
}
return next(action)
}
}
複製代碼
當action爲函數的時候,這個行爲就被攔截了,而不是派發到reducer中去找到對應的action觸發內容,這裏的action就是一個thunk函數,將dispatch和getState派發到函數中 初始化thunk函數方法以下:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
const store = createStore(
reducer,
applyMiddleware(thunk)
);
複製代碼
具體調用中能夠這麼寫
let apis=(url,params)=>{
return(dispatch,getState)=>{
fetch(url,params).then(result=>{
dispatch({
type:'GET_WEATHER_SUCCESS',
payload:result
});
}).catch(e=>{
dispatch({
type:'GET_WEATHER_ERROR',
error:error
})
})
}
}
store.dispatch(apis('https://xx.xx.xx.xx',{a:1,b:2}))
複製代碼
後續再補充別的中間件