记录一下最近项目所用到的技术React + Dva + Antd + umi ,以避免忘记。以前没有用过它们其中一个,也是慢慢摸索,了解数据整个流程。html
先了解下概念前端
React 很少说,3大框架之一;react
Dva 是由阿里架构师 sorrycc 带领 team 完成的一套前端框架,在做者的 github 里是这么描述它的:“dva 是 react 和 redux 的最佳实践”。如今已经有了本身的官网 https://dvajs.com;ios
Antd 是阿里的一套开箱即用的中台前端/设计解决方案,UI框架,官网 http://ant-design.gitee.io/index-cn;git
umi 是 dva 做者 sorrycc 最近整的新玩意,2018.2.26 发布的 1.0 版本。sorrycc 认为以前 dva 当然好,但还要用户本身引入 UI 工具 antd,打包工具 roadhog,路由 react-router,状态管理器 dva,这些很麻烦,因此弄了这个,官网 https://umijs.org;es6
在dva中主要分3层,models,services,components,其中models是最重要概念,这里放的是各类数据,与数据交互的应该都是在这里。services是请求后台接口的方法。components是组件了。github
services层:
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 } }
models层:
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:{ // 订阅监听,好比咱们监听路由,进入页面就如何,能够在这写
} )
components层:
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方法从新渲染,界面就会更新。redux
render方法何时会触发axios
当state或props变化时就会触发render,咱们通常在render里只获取props和state,尽可能不作逻辑处理(数据逻辑处理基本在render上面的函数或者models中处理)。当父组件给子组件传递props时,子组件那个props最好不要在render里面作逻辑计算赋值,否则传递过去,子数组
组件有可能拿不到最新的值。好比传了个数组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)