背景
前段时间,通过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