記錄一下最近項目所用到的技術React + Dva + Antd + umi ,以避免忘記。以前沒有用過它們其中一個,也是慢慢摸索,瞭解數據整個流程。前端
先了解下概念react
React 很少說,3大框架之一;ios
Dva 是由阿里架構師 sorrycc 帶領 team 完成的一套前端框架,在做者的 github 裏是這麼描述它的:「dva 是 react 和 redux 的最佳實踐」。如今已經有了本身的官網 https://dvajs.com;git
Antd 是阿里的一套開箱即用的中臺前端/設計解決方案,UI框架,官網 http://ant-design.gitee.io/index-cn;es6
umi 是 dva 做者 sorrycc 最近整的新玩意,2018.2.26 發佈的 1.0 版本。sorrycc 認爲以前 dva 當然好,但還要用戶本身引入 UI 工具 antd,打包工具 roadhog,路由 react-router,狀態管理器 dva,這些很麻煩,因此弄了這個,官網 https://umijs.org;github
在dva中主要分3層,models,services,components,其中models是最重要概念,這裏放的是各類數據,與數據交互的應該都是在這裏。services是請求後臺接口的方法。components是組件了。redux
export function doit (body) { return request({ method: "post", url: `${wechatApi}/doit`, data: JSON.stringify(body), }) } 這裏就是請求後臺接口的方法,其中這裏的request是封裝了axios的函數,因此它是返回的是一個promise對象,url就是要請求的地址,body就是請求參數了。 那個request以下 import axios from "axios" export default async function request (options) { let response try { response = await axios(options) return response } catch (err) { return response } }
export default { namespace: "test", //命名空間名字,必填 state: { num: 0 },//state就是用來放初始值的 // 能改變界面的action應該放這裏,這裏按官方意思不該該作數據處理,只是用來return state 從而改變界面 reducers:{ addNum ( // addNum能夠理解爲一個方法名 // 這裏state就是上面初始的state,這裏理解是舊state state, { payload: { num }}// num 是傳過來的,名字隨便起,不是state中的num,這接收一個action ) { //return新的state,這樣頁面就會更新 es6語法,就是把state所有展開,而後把num:num從新賦值,這樣後面賦值的num就會覆蓋前面的。也是es6語法,相同名字能夠寫成一個,因此上面接收處寫了num
return { ...state, num}
}, },
// 與後臺交互,處理數據邏輯的地方 effects:{
},
* fetchUser(_,{call,put}) {
// XXXXXXX代碼
}
}, subscriptions:{ // 訂閱監聽,好比咱們監聽路由,進入頁面就如何,能夠在這寫
} )
clickHandler = () => { dispatch({ type: "test/fetchNum",// 這裏就會觸發models層裏面effects中fetchNum方法(也能夠直接觸發reducer中方法,看具體狀況) ,test就是models裏的命名空間名字 payload: { numCount: ++1, }, }) }
點擊頁面按鈕,會觸發clickHandler,——>觸發models層effect的fetchNum——>觸發services層doit,獲取到後臺返回數據——>觸發models層的addNum,把返回數據傳給addNum,再去更新models裏的state,components應用了models層中的state的num的話,就會觸發頁面render方法從新渲染,界面就會更新。axios
render方法何時會觸發數組
當state或props變化時就會觸發render,咱們通常在render裏只獲取props和state,儘可能不作邏輯處理(數據邏輯處理基本在render上面的函數或者models中處理)。當父組件給子組件傳遞props時,子組件那個props最好不要在render裏面作邏輯計算賦值,否則傳遞過去,子promise
組件有可能拿不到最新的值。好比傳了個數組arr,arr在render裏作了數據處理,賦值,render會運行屢次(這裏舉例3次)因此結果多是[1,2,3] [1,2,3] [1,2],子組件拿到的值是[1,2,3]而不是最終的[1,2],因此當你出現
子組件沒法獲取父組件傳遞過來最後正確的值,看看是否是值在render作了運算賦值,解決方法就是把數據邏輯放在models層處理,而後再返回,這樣就沒問題了。
頁面要應用models層的數據要用connect
import { Component } from "react" import { connect } from "dva" class TheDemo extends Component { clickHandler = () =>{xxxx} render () { const {num} = this.props //獲取下面的num return ( <div> <button onClick={this.clickHandler}><button> <p>{num}</p> </div> ) } } //字面意思就是,把models的state變成組件的props function mapStateToProps (state) { const { num} = state.test // test就是models命名空間名字 return { num, // 在這return,上面才能獲取到 } } export default connect(mapStateToProps)(TheDemo)