【问题标题】:Calling `this.setState()` breaks flow type checking on a prop in componentWillReceiveProps调用 `this.setState()` 会中断对 componentWillReceiveProps 中道具的流类型检查
【发布时间】:2017-04-13 23:24:02
【问题描述】:

当我在它之前调用this.setState() 时,我在一个我知道是一个字符串的道具上收到一个流错误。如果我将 setState() 调用移到使用该道具的行之后,错误就会消失。我得到的错误是:

空

此类型与预期的字符串参数类型不兼容

未定义

此类型与预期的字符串参数类型不兼容

这两个错误都发生在同一行代码中。

这是组件的精简版。见componentWillReceiveProps的实现:

import React, { Component } from "react";
import apiRequest from "../../services/apiRequest";

type PropsT = {
  endpoint: ?string,
};

export default class ApiLoader extends Component {
  props: PropsT

  static defaultProps = { endpoint: null }
  state = { isFetching: true }

  componentWillReceiveProps(nextProps: PropsT) {
    if (!nextProps.endpoint) return;

    this.setState({ isFetching: true });
    this.fetch(nextProps.endpoint);       // FLOW ERROR HERE
  }

  fetch(endpoint: string) {
    apiRequest.get(endpoint)
      .then(() => this.setState({ isFetching: false }));
  }

  render(): React.Element<*> {
    return <div>Whatever.</div>;
  }
}

只需切换componentWillReceiveProps 中最后两行的顺序即可修复它:

this.fetch(nextProps.endpoint);      // NO ERROR!
this.setState({ isFetching: true });

这只是 Flow 中的一个错误,还是我遗漏了什么?

【问题讨论】:

    标签: javascript reactjs flowtype setstate


    【解决方案1】:

    这是由于类型优化失效:https://flow.org/en/docs/lang/refinements/#toc-refinement-invalidations

    将endpoint 提取到它自己的变量中,你应该可以开始了。

    【讨论】:

    • 是的,这行得通。然而,在理想世界中,flow 应该能够告诉我,在我的实现中,setState() 不会修改道具的值,对吗?还是我真的错过了setState 可能产生的副作用?我之所以这样问,部分是因为我对我必须修改我的编码风格感到有点沮丧,这样当我认为它应该能够在没有额外帮助的情况下解决问题时,flow 才知道发生了什么:)
    • 你是对的,这种分析在理论上是可能的,我相信你也是对的,在这种情况下,调用setState 是安全的。但是,出于性能原因,Flow 在执行类型检查时只能查看另一个函数的类型(而不是实现)。因此,为了让 Flow 避免丢弃细化,您必须在类型中表达纯度。 setState 不是严格意义上的纯粹,因此您还必须以某种方式表达它可能修改的内容的类型。显然,这很快就会变得复杂而令人困惑。
    • 顺便说一句,我理解你的沮丧。类型系统对你能做什么有很大的限制。 Flow 在类型系统中具有很强的表现力,但如果你不习惯使用它,它肯定会很烦人。我容忍不利因素,因为我相信有明显的好处,但这并不意味着不利因素不存在。
    猜你喜欢
    • 1970-01-01
    • 2016-12-03
    • 2018-08-20
    • 2015-02-18
    • 2020-12-01
    • 2017-07-31
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多