背景
前段时间,通过react+typescript+umi构建项目,在使用装饰器写法使用dva进行状态管理的时候发现,装饰器写法在tslint中报错了,提示作为表达式调用,无法解析类修饰器的签名???
附上代码
import React, { Component } from 'react'
import { connect, UserInfoModelState, Loading } from 'umi';
@connect(({ userInfo, loading }: { userInfo: UserInfoModelState; loading: Loading }) => ({
userInfo,
// dva-loading可以自动处理loading状态
loading: loading.models.index,
}))
export default class User extends Component<any, any> {
constructor(props: any) {
super(props);
console.log(props);
this.state = {
username: props.userInfo.name
}
}
// 调用userInfo模块的reducers里的changeName方法
private changeName = () => {
const { dispatch } = this.props;
dispatch({
type: 'userInfo/changeName',
payload:{
name: '李四'
}
})
}
render() {
return (
<div>
<div onClick={this.changeName}>更改用户名</div>
<div className="title">用户名{this.props.userInfo.name}</div>
</div>
)
}
}
报错
思路
- 法一
直接弃用装饰器写法,改用高阶组件的写法,ok,完美解决问题
import React, { FC } from 'react';
import { UserInfoModelState, ConnectRC, Loading, connect } from 'umi';
interface PageProps {
userInfo: UserInfoModelState;
loading: boolean;
}
const IndexPage: FC<PageProps> = (props) => {
const handleClick = () => {
const { dispatch } : any = props;
dispatch({
type: 'userInfo/changeName',
payload:{
name: '李四'
}
})
}
return (
<div>
<div onClick={handleClick}>更改用户名</div>
<div className="title">用户名{props.userInfo.name}</div>
</div>
)
};
export default connect(({ userInfo, loading }: { userInfo: UserInfoModelState; loading: Loading }) => ({
userInfo,
loading: loading.models.index,
}))(IndexPage);
- 法二
难道接下来写代码,react+typescript就一直不能用装饰器写法么???我不信
我们看看,说到底,还是类型的问题
那么突发奇想,创建一个变量接收connect,并给这个变量定义类型为any,是否可以解决这个类型问题呢?
import React, { Component } from 'react'
import { connect, UserInfoModelState, Loading } from 'umi';
const connect1: any = connect; // 由于直接使用@connect tslint会报错,所以重新赋值再使用装饰器写法
@connect1(({ userInfo, loading }: { userInfo: UserInfoModelState; loading: Loading }) => ({
userInfo,
// dva-loading可以自动处理loading状态
loading: loading.models.index,
}))
export default class User extends Component<any, any> {
constructor(props: any) {
super(props);
console.log(props);
this.state = {
username: props.userInfo.name
}
}
// 调用userInfo模块的reducers里的changeName方法
private changeName = () => {
const { dispatch } = this.props;
dispatch({
type: 'userInfo/changeName',
payload:{
name: '李四'
}
})
}
render() {
return (
<div>
<div onClick={this.changeName}>更改用户名</div>
<div className="title">用户名{this.props.userInfo.name}</div>
</div>
)
}
}
完美解决问题,可以愉快使用装饰器写法了。
如果有更好的解决办法,欢迎留言探讨。
文章参考及思路来源
https://segmentfault.com/q/1010000014835057