react+typescript装饰器写法报错的解决办法

react+typescript装饰器写法报错的解决办法

背景

前段时间,通过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
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值