如何正确键入将异步获取其值的组件状态

时间:2019-07-11 07:18:00

标签: javascript reactjs typescript

我的状态下有一个属性product,其开头是未定义的,后来被设置为来自数据库的对象。即使在引用this.state.product.name之前检查了属性是否存在,我仍然收到此错误:

2352: Object is possibly undefined.

interface Product {
  _id: string;
  name: string;
  images?: string[];
  color: string;
};

interface State {
  product: Product | undefined;
};

class ProductInfo extends React.Component<{ }, State> {
  state = {
    product: undefined
  };

  componentDidMount() {
    fetch(url)
      .then((res: any) => res.json())
      .then((res: Product) => this.setState(({ product: res }));
  }

  render() {
    if (this.state.product) {
      return (
       <h1>{this.state.product.name}</h1>
      );
    } else {
      return <h1>Spinner goes here</h1>
    }
  }
}

错误出现在我引用this.state.product.name的那一行上。

2 个答案:

答案 0 :(得分:0)

我认为这是ts的错误,请参见GitHub问题:https://github.com/Microsoft/TypeScript/issues/29642

您可以尝试如下定义初始状态:

state = {
  product: {
    _id: '',
    name: '',
    ... // other stuff of product too.
  }
};

然后在render()中检查this.state.product._id,而不只是this.state.product。像这样:

render() {
  if (this.state.product._id) {
    return <h1>{this.state.product.name}</h1>;
  } else {
    return <h1>Spinner goes here</h1>;
  }
}

CodeSandbox演示https://codesandbox.io/s/beautiful-sinoussi-5iw3j?fontsize=14

现在您还可以安全地更新状态界面,以删除未定义的内容,例如:

interface State {
  product: Product;
}

答案 1 :(得分:0)

您可以做两件事,我知道。首先,您可以明确地说您的州是州类型的,就像这样:

state: State = {
    product: undefined
};

或者您可以使用非null断言运算符,因为您可以确定它不是未定义的,然后将状态对象转换为Product。

if (this.state.product) {
    return (
    //                          ▼__________▼
        <h1>{(this.state.product! as Product).name}</h1>
    );
} else {
    return <h1>Spinner goes here</h1>
}