简介
这是一个关于阿里团队Ant Design关于react技术栈的开发体验,
主要技术栈为:react,typescript ,Umi.js,Dva.js......
在之前的工作中,更多时候我的技术选型是Vue或者Angular,但怀着学无止境的想法,在公司的新项目中决定使用React(毕竟你们都在吹!!)。在正式的项目开始前有必要先熟悉React的开发生态,于是基于AntDesign-Pro写了一个小Demo。Demo虽小,但本人觉得还是很好的囊括了一些今后开发会遇到的坑,所以有必要总结记录下来。技术有限,有错请骂,骂完就改。
目录
- AntDesignPro
- typescript
- 路由
- Redux(Dva.js)
- 与服务器交互
- 代理
- yield
AntDesignPro 简介
以下为antdesignpro的目录结构图:
没有什么好说,上面那张图就很详细了。
typescript
typescript并不是一门新技术,不过是JavaScript的一个超集,解决了JavaScript一直被诟病的弱类型语言的问题。故在学习中不需要投入过多时间精力去学习它,以下是我觉得有必要特别学习的地方:
接口
TypeScript的核心原则之一是对值所具有的结构进行类型检查。在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
interface Mes{ str: string;}function hello(mes: Mes){ console.log(mes.str);}let mes = { "str":"hello TypeScript"};hello(mes);复制代码
泛型
要创建一个可重用的组件,其中的数据类型就必须要兼容很多的类型,那么如何兼容呢,TypeScript提供了一个很好的方法:泛型
function Test(param: T): T{ return param}复制代码
路由
AntDesignPro使用的路由为经过Umi.js封装过的路由(其实就是加了层毫无意义封装)。
UmiJs会自动生成约定式路由,但如果你倾向于使用配置式的路由,也可以配置routes。
配置位置为:
routes.ts:
exports.routeOBJ = [ { path: '/login', component: '../layouts/main/main', }, { path: '/', component: '../layouts/main/main', routes:[ { path:'/', redirect:'/discover/recommend' }, { path:'/discover/recommend', component:'./discover/recommend' } ] },];复制代码
在此我曾深陷一个巨坑之中无法自拔,在routes中,path:'/login' 路由必须放在path:‘/ ’前,否则无论你如何跳转,你都跳转不到login!!
Redux(DvaJs)
就像是Vue中的Vuex一样,Redux做着跟Vuex一样的工作,只是在AntDesignPro中使用的是DvaJS(又是一个瞎**封装)。
这里只是大概讲一下Redux的应用,详细的API讲解以后再说。
首先记住以下代码:
connect(({ playlist }: ConnectState) => ({ playlist,}))(login);复制代码
这段代码的作用就是将redux里model的数据映射到login这个reactComponent的Props中,这样你就可以使用this.props.dispatch,如下:
this.props.dispatch({ type: 'playlist/fetchPlayList', callback:res=>{ console.log(res); this.state.hot_recommend = res.playlists.slice(0,8) } });复制代码
巨坑来了!!在使用this.props.dispatch时请千万注意不要在render(){}里面直接使用,后果就是会一直死循环的执行直到你的小破本死机(别问我怎么办,问就是重启)。如果你要在页面初始化的时候调用,那请放在componentDidMount和()或者其他勾子函数中。
与服务器交互
在 Ant Design Pro 中,一个完整的前端 UI 交互到服务端处理流程是这样的:
- UI 组件交互操作;
- 调用 model 的 effect;
- 调用统一管理的 service 请求函数;
- 使用封装的 request.ts 发送请求;
- 获取服务端返回;
- 然后调用 reducer 改变 state;
- 更新 model。
这种模式看起来很繁琐,但其实不然。刚接触的时候确实有些排斥,但当你接受了这种看似不友好的流程后,你会发现你的项目结构极其明朗。
先是Service.ts,使用封装好的函数request定义接口
import request from '@/utils/request';export async function playlist(): Promise{ return request('/server/top/playlist');}复制代码
在Models中通过异步机制调用接口函数
effects: { *fetchPlayList({_,callback}, { call, put }) { console.log('playlist'); const response = yield call(playlist); if (callback && typeof callback === 'function') { callback(response) } yield put({ type: 'savePlaylist', payload: response, }); }, },复制代码
在你的react页面中通this.props.dispatch调用model中的函数及可完成与服务器的对接。
this.props.dispatch({ type: 'playlist/fetchPlayList', callback:res=>{ console.log(res); } });复制代码
代理
AntDesignPro的代理放在里config里面:
Yield
在上面的models代码中,一定会出现yield,熟悉es6的同学肯定知道它的作用。yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。
yield无法单独工作,需要配合generator(生成器)的其他函数
function* test(){ console.log(0); yield console.log(1); yield console.log(1); yield console.log(1); } test() 没有输出 test().next() /// 0 1复制代码
yield在生成器中的作用类似与断点,而next()则是打开这个断点的唯一钥匙,一个next()打开一层以此类推。
结尾
使用这套技术栈有时候确实很给人添堵,有时候就是有种山路十八弯的感觉。但总体体验还算可以,项目工程化的思想很好,组件的封装也很简洁(完全看不懂)。这个小demo也算是React技术栈的起步吧,写篇小文总结一下。