【问题标题】:Typescript and react conditional render打字稿和反应条件渲染
【发布时间】:2020-08-17 07:16:20
【问题描述】:

我是 typescript 的新手,不是 FE 开发方面的专家。我遇到了看起来很基本的问题,但我没有找到任何解决方案。也许我只是不知道如何正确地用谷歌搜索它。 在反应组件中,我有一个按钮,在某些情况下被禁用,这会触发组件的功能:

import React, {Component} from 'react';

type DraftCompany = {
    id: null
    name: string,
};

type Company = Omit<DraftCompany, 'id'> & {
    id: number;
};

type Props = {
    company: Company | DraftCompany,
    onDeleteCompany: (companyId: number) => void,
}

class CompanyRow extends Component <Props> {
    handleDeleteCompany = () => {
        this.props.onDeleteCompany(this.props.company.id);
    };

    render = () => {
        return (
            <div>
                <div>{this.props.company.name}</div>
                <div>
                    <button disabled={this.props.company.id === null} onClick={this.handleDeleteCompany}/>
                </div>
            </div>
        )
    }
}

export default CompanyRow;

我在调用this.props.onDeleteCompany(this.props.company.id); 时遇到打字稿错误,这表明我有可能将null 作为参数传递。我完全理解为什么打字稿会给我这个错误,问题是:处理这个错误的最佳方法是什么?

我找到了 3 种方法:

1) 添加 'if' 保护

handleDeleteCompany = () => {
        if (this.props.company.id) {
            this.props.onDeleteCompany(this.props.company.id);
        }
    };

它可以工作,但我不喜欢在每个函数中添加这样的保护,如果有人删除了disabled 逻辑,我想立即收到控制台错误告诉我,而不是让它被默默吞下。在我的项目中,我有很多依赖于渲染的此类代码,我怀疑在任何地方添加此类检查是否是最佳实践。也许我错了。

2) 将as 应用于字段操作员:

 handleDeleteCompany = () => {
        this.props.onDeleteCompany(this.props.company.id as number);
    };

它有效,但看起来有点 hacky。

3) 将as 运算符应用于整个对象并将其传递给函数:

 <button disabled={this.props.company.id === null} 
         onClick={() => this.handleDeleteCompany(this.props.company as Company)}/>
 handleDeleteCompany = (company: Company) => {
        this.props.onDeleteCompany(company.id as number);
    };

它有效,但看起来我没有必要传递我可以从道具中获取的函数本身的值。我不确定这样做是否是最佳做法。

我确信应该有一些纯粹的打字稿解决方案,例如将 Props 类型定义为联合或使用条件类型与anynever 的某种组合。但我还没有弄明白。

这是一个游乐场: playground

【问题讨论】:

  • 问题是onDeleteCompany 做了什么。它是否接受 idnull
  • @kinduser 不接受null,总是数字。
  • 那么 if 守卫 是要走的路。
  • @kinduser 感谢您的意见!所以我们不应该依赖渲染中的“ifs”并且总是添加一个签入函数本身吗?如果不是打字稿,只是普通的 js 组件,你会建议同一个守卫吗?

标签: javascript reactjs typescript


【解决方案1】:

我认为根据您的要求

如果有人删除了禁用的逻辑,我想立即收到控制台错误告诉我

有一个非常简单的解决方案非常有意义,只需将您的 onDeleteCompany 类型从 (companyId: number) =&gt; void 更改为 (companyId: number | null) =&gt; void,TypeScript 就会很高兴。

这在语义上也对您有意义,因为您希望运行时在 companyId 为空时报告此错误。那么你应该允许带有null的companyId作为参数传入。

【讨论】:

    【解决方案2】:

    您可以使用! 运算符强制编译假定值永远不是nullundefined

     handleDeleteCompany = () => {
            this.props.onDeleteCompany(this.props.company.id!);
        };
    

    【讨论】:

    • 谢谢,不知道!在您看来,这是描述情况下的最佳选择吗?
    • 为什么要强制 ts 编译并假设 id 永远不会为空,即使有一个接口实际上假设 id 可以为空。它几乎没有任何意义。
    • 只要你能确定id 永远不会在那里为空,我会说! 是可行的。我认为它比类型转换或没有elseif 更清楚地表达了您的意图。仅在边缘情况下使用!,当您 100% 确定并控制所有呼叫站点时。
    猜你喜欢
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2022-07-11
    • 2020-10-19
    • 1970-01-01
    • 2022-01-17
    • 2019-03-25
    相关资源
    最近更新 更多