流状态对象的条件值?

时间:2017-06-22 03:57:46

标签: reactjs flowtype

如何正确检查此文件, 该组件具有状态的条件呈现基础, 流程说Property cannot be accessed on possibly null value

如果我有一个更复杂的状态结构,如{user.owner.name},该怎么办... 如何正确设置类型?

type User = {
  title: string,
  description: string,
  year: string,
  imdbID: string,
  poster: string,
  trailer: string
};

class AllUser extends React.Component {
  state: {
    repos: Array<?User>,
    repos2: Array<?User>
  };

  handleChange: () => void;
  filterItem: () => void;

  constructor() {
    super();
    this.state = {
      repos: [],
      repos2: []
    };
    this.handleChange = this.handleChange.bind(this);
    this.filterItem = this.filterItem.bind(this);

  }

  componentDidMount() {
    if (this.state.repos.length === 0) {
      fetchPopularRepos("all").then((repos: Array<?User>) => {
        this.setState({
          repos: repos,
          repos2: repos
        });
      });
    }
  }

  render() {
    if (this.state.repos.length === 0) {
      return (
        <div>loading</div>
      );
    }
    return (
      <div>
        {this.state.repos.map(repo => <p>{repo.name}</p>)}
      </div>
    )
  }
}

1 个答案:

答案 0 :(得分:1)

repos: Array<?User>表示repos属性是“一系列项目,其中每个项目可以是nullundefined,或User

repos: ?Array<User>表示repos属性为“nullundefined,或项目数组,其中每个项目必须为User

repos: Array<User>表示repos属性是“一系列项目,其中每个项目必须为User

由于您使用的是第一个,

this.state.repos.map(repo => <p>{repo.name}</p>)

you Flow认为repos将是一个数组,但您的类型声明Array<?User>表示回调中的repo可能是Usernullundefined,因为.namenull值上的undefined会抛出异常,因此Flow会抛出错误。这是给定类型的正确行为。

您分配repos的两个地方是

this.state = {
  repos: [],
  repos2: []
};

fetchPopularRepos("all").then((repos: Array<?User>) => {
  this.setState({
    repos: repos,
  });
});

所以问题是,fetchPopularRepos会返回包含nullundefined值的数组吗?这对我来说似乎很奇怪。如果某个项目不是用户,则根本不应将其包含在数组中。包含null值只会引起混淆。

鉴于此,此处的修复方法是更改​​

.then((repos: Array<?User>) => {

.then((repos: Array<User>) => {

所以你保证数组只包含User个对象,然后改变

  state: {
    repos: Array<?User>,
    repos2: Array<?User>
  };

  state: {
    repos: Array<User>,
    repos2: Array<User>
  };