React的变化很快,在我之前用习惯了直接hashHistory、browserHistory,而react-router4改变后就不习惯了,索性就直接使用了阿里的umijs。
下面是我学习umi过程中的一些心得。
学习前端框架,直接看官方文档是最好的学习方法umi官方文档链接,但是总的来说,其实umi官方文档写的教程并不是很详细,它可能面向的是基础比较好的前端开发者的。但是,你的问题都是可以在其github项目的issue中找到解答的,我这里找了一个能解决我好多问题的网友总结的issue链接。
首先还是说一下umi的优点:我个人体会最显著的是,不需要你配置很多其他的参数,不需要你手动写react-router,因为其默认的pages下的文件夹名字就直接是路由的路径,也不需要你自己配置dll,因为内部直接内置了dll。同时umi默认使用dva代替react-redux,dva可以说是一个零api的数据流方案。
再一来说一说我只有redux-thunk和比较老版本react基础的在学习umi+dva+ts技术栈过程中碰到的几个问题:
1、effects和reducer的调用重名问题
一般来说,修改state的时候使用reducer,其他时候都用effects,如果名称一样,在dva@2后,只有effect会调用,所以两个不能重名
2、在有状态组件中,已经绑定mapStateToProps,但是this.props中的属性无法被读取
这个是ts的问题,我在stackoverflow上提的问题如链接:我的提问,本质上是使用组件范型的方式解决问题。这一点在Hello React and TypeScript中也提到了。
3、less module使用问题
本来umi默认配置是支持less,但是我使用umi2.6.12自带的脚手架进行配置,根目录下的typings.d.ts中少了declare module '*.less';
,导致less无法作为模块导入。
4、antd Button控件报错
这个问题已经被修复,这里贴出我原本提问的链接:我的提问,该问题已经被解决,只需要更改@types/react的版本就可以。
5、layout问题
其实我对umi框架的layout还不是很理解很熟悉,但是如果想要某些页面禁止使用一些layout,只需要判断props.location.path
属性进行一些选择就可以了:
import React from 'react';
import styles from './index.css';
import Header from '../components/header';
// export default BasicLayout;
export default (props: any)=>{
//设置主页面的登陆页面样式
if (props.location.pathname === '/') {
return (<div>{props.children}</div>)
}
if(props.location.pathname === '/video') {
return (<div>{props.children}</div>);
}
//设置其他页面的样式,设置header和footer样式
return (
<div className={styles.normal}>
<Header></Header>
{props.children}
</div>
);
}
6、项目无法上传到git
我在git commit
这一步的时候,会提示一些错误,但是不影响项目运行,其中比较烦的就是提示一些标签没有self-closing,我使用的antd的Menu.Item都让我自闭合那是不可能的,我怎么在Item中填我的Menu值呢?所以我采取了一种比较暴力的手段——每次上传项目的时候都禁用package.json文件的scripts属性中的"precommit": "lint-staged"
,就可以上传成功了。可能有其他更好的手段解决,但是我图方便就这样进行了项目的上传。
7、路由跳转
这个其实不是我碰到的问题,但是umi的路由跳转真的很方便!我最常用的两种跳转方式有:一是使用import router from 'umi/router
,然后直接router.push就可以,第二种是import { routerRedux } from 'dva/router'
,然后routerRedux.push就可以进行跳转。这两种跳转可以说是满足了我做的项目的所有需求,不需要手动写一个Provider,也不需要react-router4后对于browserHistory的繁杂配置,直接可以进行解决。
8、props属性上不存在dispatch问题
这其实是一个ts的问题,在tsx文件中,props.dispatch是需要规定类型的,如果嫌麻烦可以在头上使用<any,any>的形式来表示比如:class xxx extends React.Component<any,any>{
这样就可以解决props.dispatch问题了
这个问题还有个解决的方法,就是在tsconfig.json文件中,设置"noImplicitAny":false
,这样就可以设置默认any类型了,但是这样对ts支持不太好,推荐上面的方法。