【问题标题】:React - Flow & Conditional renderingReact - 流和条件渲染
【发布时间】:2019-10-02 09:38:09
【问题描述】:

我将 Flow 与 React-Native 一起使用。我遇到了 VSCode 提出的流程问题,我不知道如何更改我的方法以符合流程类型。

/* @flow */

type RandomType = {
  id: number,
  unit: string,
};

const renderData = (data: RandomType) => { return data.id };

const getRandomTypeOrEmpty = (isempty: boolean): RandomType | {} => {
    if (isempty) { return {} }
    return { id: 1, unit: 'litres'}
};

const data = getRandomTypeOrEmpty(true);
if (data && data.id ) { renderData(data) };

16: if (data && data.id) { renderData(data) }; ^ 无法调用 data 绑定到 datarenderData,因为属性 id 在对象类型 [1] 中缺失,但在 RandomType [2] 中存在。

这是我的问题:

我有一个函数可以为我提供 数据,它可以是 RandomType空对象 {}。 然后,我必须调用一个必须接受 RandomType 参数的函数。

所以我根据 data 值和条件调用此函数。 但是,即使永远不会使用不是 RandomType

的数据调用此函数,Flow 仍然会引发问题

我该如何解决这个错误?

感谢您的宝贵时间

【问题讨论】:

    标签: javascript reactjs react-native flowtype


    【解决方案1】:

    您应该使用maybe type 来指示可选属性。

    type RandomNumber = {
      id?: number,
      unit?: string
    };
    
    const a: RandomNumber = {}; // works
    

    现在RandomNumber 类型的变量在为空时仍然有效。

    https://flow.org/try/#0PTAEAEDMBsHsHcBQiAuBPADgU1AJQIYB2AJrALYByArmQEZYBOoAvKAN6KigCWxA-AC5QhGvQYAaTqCqFuKQaADOKBt0IBzRAF8A3MgDGsQstD4hBEuWp1GLdrsRA

    【讨论】:

    • 但是如果我在调用它之前不检查 id 是否存在,我的函数 renderData 可能会失败?理想情况下,我想强制一个参数包含这些属性,以避免检查它们是否存在。
    • 它会“失败”吗?它只会返回 undefined
    【解决方案2】:

    问题是您在getRandomTypeOrEmpty 上的返回类型可能会返回一个不精确的对象{},它上面可能有任何键。这意味着它可能有一个id 键,因此检查data.id 不允许流确定您正在处理RandomType

    您可以改为返回一个确切的空对象,然后问题就消失了:

    type RandomType = {
      id: number,
      unit: string,
    };
    
    const renderData = (data: RandomType) => { return data.id };
    
    const getRandomTypeOrEmpty = (isempty: boolean): RandomType | {||} /* return an EXACT empty object */ => {
        if (isempty) { return {}.freeze } // <-- freeze the type so it's an exact object
        return { id: 1, unit: 'litres'}
    };
    
    const data = getRandomTypeOrEmpty(true);
    if (data.id ) { renderData(data) }; // <-- only need to check for presence of id
    

    Flow link

    【讨论】:

    • 不错的答案!另外,我可以进一步使用 lodash 吗?为什么要专门检查 id 而不是单位属性?我可以使用 _.isEmpty(data) 吗?
    • 我没有使用 _.isEmpty,它可能提供也可能不提供必要的类型细化级别。您可以改为检查data,两者都可以。关键是,当查看 RandomType 或空对象时,any 键的存在将足以让流知道它是 RandomType。这有意义吗?
    • 好的。但是,如果我想做一些通用的东西,我可以使用一个函数 isEmpty,我可以使用任何 RandomType 定义:tiny.cc/2kyq6y
    • 嗯,Flow 并不是那么聪明,一旦你离开它,它就无法在 isEmpty 函数中保留类型细化。在此处阅读更多信息:flow.org/en/docs/lang/refinements。 PS如果你喜欢我的回答,请点赞。 :-)
    • 我尝试做某事like this,但 Flow 可能不太了解 Object.keys。
    【解决方案3】:

    试试这个

    
    /* @flow */
    
    type RandomType = {
      id ?: number,
      unit ?: string
    };
    
    const renderData = (data: RandomType) :number => { return data.id };
    
    const getRandomTypeOrEmpty = (isempty: boolean): RandomType => {
        return isempty ? {} : { id: 1, unit: 'litres'}
    };
    
    const data = getRandomTypeOrEmpty(true);
    if (data && data.id ) { renderData(data) };
    

    【讨论】:

      猜你喜欢
      • 2021-05-22
      • 1970-01-01
      • 2019-01-02
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 2021-10-11
      相关资源
      最近更新 更多