在使用React和API时如何解决“ TypeError:items.map不是函数”?

时间:2019-03-09 20:50:46

标签: javascript reactjs error-handling typeerror

我是React的新手,正在尝试从API提取一些信息,但是在使用.map函数将检索到的数据传递到数组中时,始终会出现此错误:

  

TypeError:items.map不是函数。

我对JavaScript不太熟悉,所以我不完全了解这里发生了什么。我已经包含了我的代码:

import React, { Component } from "react";
import "./App.css";

class App extends Component {
  constructor() {
    super();
    this.state = {
      items: [],
      isLoaded: true
    };
  }

  componentDidMount() {
    fetch("http://www.colr.org/json/colors/random/7")
      .then(res => res.json())
      .then(json => {
        this.setState({
          isLoaded: true,
          items: json
        });
      });
  }

  render() {
    var { items, isLoaded } = this.state;
    var itemInfo = items.map(item => (
      <div key={item.colors.id}>Hex:{item.colors.hex}</div>
    ));

    if (!isLoaded) {
      return <div>{itemInfo}</div>;
    } else {
      return <div className="App">{itemInfo}</div>;
    }
  }
}

export default App;

3 个答案:

答案 0 :(得分:2)

由于处于状态的items数组最初是一个空数组,所以当您将items更改为非数组内容时会出现此错误。

看看问题中来自API的响应,解析后,您将从JSON中获得一个对象。您要在响应中使用的数组位于colors属性下,并且该数组中的每个元素都具有idhex属性。

class App extends Component {
  // ...

  componentDidMount() {
    fetch("http://www.colr.org/json/colors/random/7")
      .then(res => res.json())
      .then(res => {
        this.setState({
          isLoaded: true,
          items: res.colors
        });
      });
  }

  render() {
    var { items, isLoaded } = this.state;
    var itemInfo = items.map(item => <div key={item.id}>Hex:{item.hex}</div>);

    // ...
  }
}

答案 1 :(得分:0)

由于您没有为任何类型指定类型,而且itemsArray并不清楚(甚至对于人类读者也是如此),因此您应明确告知TypeScript将其用作数组。

您为此使用Type Assertion。应该是这样的:

(items as Array<YourArrayElementType>).map(/* .. */);

但是,作为一种好的做法,您应该始终明确指定要声明的任何内容的类型。这样,您代码库中的所有内容都将被静态键入。对于来自外部的任何内容(例如API请求),您都应该将信息转换为您定义的interfaces

答案 2 :(得分:0)

就您的特定问题而言,Tholle是绝对正确的...我将进一步清理您的代码,如下所示:

import React, { Component } from 'react';

class App extends Component {
  state = { items: [], isLoading: true, error: null };

  componentDidMount() {
    fetch('http://www.colr.org/json/colors/random/7')
      .then(res => res.json())
      .then(json => {
        this.setState({
          isLoading: false,
          items: json.colors,
        });
      })
      .catch(error =>
        this.setState({ error: error.message, isLoading: false }),
      );
  }

  renderColors = () => {
    const { items, isLoading, error } = this.state;

    if (error) {
      return <div>{error}</div>;
    }

    if (isLoading) {
      return <div>Loading...</div>;
    }

    return (
      <div>
        {items.map(item => (
          <div key={item.id}>Hex: {item.hex}</div>
        ))}
      </div>
    );
  };

  render() {
    return <div>{this.renderColors()}</div>;
  }
}

export default App;