简体   繁体   English

React + Typescript:如何为从 componentDidMount 填充的数组定义接口?

[英]React + Typescript: How to define interface for an array that's populated from componentDidMount?

I am exploring React and Typescript and I stuck on a problem of how to define an interface for an array where are stored data from an API.我正在探索 React 和 Typescript,我遇到了一个问题,即如何为存储来自 API 的数据的数组定义接口。

Here's what I have:这是我所拥有的:

interface IState {
  loadingData: boolean;
  apiData: Array<string>;
}

class Contact extends Component<IProps, IState> {
  constructor(props: IProps) {
    super(props);
    this.state = {
      loadingData: true,
      apiData: []
    };
  }

  componentDidMount() {
    const apiUrl = 'http://jsonplaceholder.typicode.com/users';
    fetch(apiUrl)
      .then((response) => response.json())
      .then((data) => {
        console.log('This is your data', data);
        this.setState({ loadingData: false, apiData: data });
      })
      .catch(error => console.log('error: ', error));
  }
  ...

After running this code, though, I receive the following error:但是,运行此代码后,我收到以下错误:

Error: Objects are not valid as a React child (found: object with keys {id, name, username, email, address, phone, website, company}). If you meant to render a collection of children, use an array instead.
    in div (at Contact.tsx:39)
    in div (at Contact.tsx:33)
    in Contact (created by Context.Consumer)
    in Route (at Main.tsx:26)
    in div (at Main.tsx:23)
    in div (at Main.tsx:16)
    in Router (created by HashRouter)
    in HashRouter (at Main.tsx:15)
    in Main (at src/index.tsx:9)

What's the key to properly set up an interface for an array?为数组正确设置接口的关键是什么?

EDIT: Adding the render function:编辑:添加render function:

render() {
    return (
      <div>
        <div>
          <h5>API Data</h5>
          {this.state.loadingData ? (
              'Loding data...'
            ) : (
              this.state.apiData
            )
          }
        </div>
      </div>
    );
  }

You can't render an array in react.你不能在反应中渲染一个array

{this.state.loadingData ? (
   'Loding data...'
  ) : (
    this.state.apiData 
     && this.state.apiData.map(item => <p key={item.id}>{item.name}</p>
  )
}

this.state.apiData && this.state.apiData.map will check if apiData exists (not falsy, this won't protect you from it being a wrong type) and then run call the map. this.state.apiData && this.state.apiData.map will check if apiData exists (not falsy, this won't protect you from it being a wrong type) and then run call the map.

And you need to update your interface你需要更新你的界面

interface IState {
  loadingData: boolean;
  apiData: ApiData[];
}

interface ApiData {
  id: string
  name: string
  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM