如何在传递给构造函数的箭头函数中访问类属性?

时间:2020-01-25 19:18:36

标签: typescript

我在React登录页面上定义了一个用于呈现身份验证方法的类,该界面包括一个我想覆盖的默认呈现函数。

class AuthMethod {
    constructor(initializer: Pick<AuthMethod, 'id'> & Partial<AuthMethod>) {
        Object.assign(this, initializer);
    }
    id!: string;
    text: string = "";
    enabled: boolean = false;
    icon: React.ReactNode = React.Fragment;
    render: () => React.ReactNode = () => (
        <WhiteIconButton key={this.id} disabled={!this.enabled} >
            {this.icon}
        </WhiteIconButton>
    );
}

我初始化了这些数组以供在某些地方使用(例如登录表单):

const authMethods: AuthMethod[] = [
    new AuthMethod({
        id: "auth_facebook",
        text: "Sign in with Facebook",
        enabled: false,
        icon: <FontAwesomeIcon icon={faFacebookSquare} />,
        // render: () => this.icon  // This doesn't work
    }),
    new AuthMethod({
        id: "auth_twitter",
        text: "Sign in with Twitter",
        enabled: false,
        icon: <FontAwesomeIcon icon={faTwitter} />
    }),
    new AuthMethod({
        id: "auth_google",
        text: "Sign in with Google",
        enabled: true,
        icon: <FontAwesomeIcon icon={faGoogle} />
    })
];

稍后我可以像这样渲染它们:

<div className={classes.socialLine}>
    { authMethods.map(m => m.render()) }
</div>

问题是我无法使用使用类属性的箭头覆盖“ render”箭头,在Facebook示例中,如果我取消注释“ render:”行,则会收到错误消息“包含箭头函数捕获“ this”的全局值”。

如何在提供的箭头功能中访问成员属性?

编辑:您可以在这里运行它:https://codesandbox.io/s/tender-bhabha-8jdmf?fontsize=14&hidenavigation=1&theme=dark

只需取消注释“ render:”行即可查看问题。

解决方案:

感谢jcalz提供了箭头函数无法访问“ this”属性的答案(因为它绑定到创建该属性的任何“ this”)。因此解决方案是使用“正常”功能(非箭头)。我以为当类定义中的签名是箭头函数时,这是行不通的,但事实并非如此,解决方案是:

  new AuthMethod({
    id: "auth_facebook",
    text: "Sign in with Facebook",
    enabled: false,
    icon: <FontAwesomeIcon icon={faFacebookSquare} />,
    render: function() {
      return this.icon;
    }
  }),

您可以在此处查看它的运行情况:https://8jdmf.csb.app/

1 个答案:

答案 0 :(得分:1)

箭头功能do not have their own this context与非箭头功能(例如,用function关键字定义的功能)不同。因此,箭头功能体内对this的任何提及实际上都将引用this在其词法上下文中所指的内容,而这并不是您想要的。

这里最直接的解决方案是放弃箭头功能。您可以使用function(){return this.icon}之类的匿名函数,也可以使用method syntax之类的终止符:

  new AuthMethod({
    render(){return this.icon}, 
    id: "auth_facebook",
    text: "Sign in with Facebook",
    enabled: false,
    icon: <FontAwesomeIcon icon={faFacebookSquare} />
  }),

这应该可行,并且可以说是您正在做的事情的常规方式。好吧,希望能有所帮助;祝你好运!