Как исправить «TypeError: items.map не является функцией» при работе с React и API? - PullRequest
1 голос
/ 09 марта 2019

Я новичок в React и пытаюсь получить некоторую информацию из API, но продолжаю получать эту ошибку, когда использую функцию .map для передачи полученных данных в массив:

Ошибка типа: 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 ]

2 голосов
/ 09 марта 2019

Поскольку массив items в состоянии изначально является пустым массивом, вы получаете эту ошибку, когда вы заменяете items на что-то, что не является массивом.

Глядя на ответ от API на ваш вопрос, вы получите объект из вашего JSON после того, как проанализируете его. Массив, который вы хотите использовать в ответе, находится в свойстве colors, и каждый элемент в этом массиве имеет свойства id и hex.

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>);

    // ...
  }
}
0 голосов
/ 10 марта 2019

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;
0 голосов
/ 09 марта 2019

Поскольку вы не указываете типы для чего-либо, и не совсем понятно (даже для человека-читателя), что items является Array, вы должны явно указать TypeScript использовать его в качестве массива.

Для этой цели вы используете Тип подтверждения . Должно быть что-то вроде:

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

Однако в качестве хорошей практики вы всегда должны явно указывать тип всего, что вы объявляете. Таким образом, все внутри вашей кодовой базы будет статически типизировано. Для всего, что приходит извне (например, запросы API), вы должны преобразовать информацию в interface s , которую вы определяете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...