ReactJS: TypeError: this.state.data.map не является функцией

Может кто-нибудь, пожалуйста, помогите мне с этим. Я получаю ошибку, описанную в заголовке этого вопроса. Я хочу поместить данные JSON в компонент реагирующей сетки. Эта библиотека может быть найдена на ( https://github.com/STRML/react-grid-layout)

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import Employee from './Employee'; 
import "./react-grid-layout/css/styles.css";
import "./react-resizable/css/styles.css"


var ReactGridLayout = require('react-grid-layout');

var data = [];

class MyFirstGrid extends React.Component {
    constructor() {
        super();
        this.state = {
            data: []
        };
    }

    componentDidMount(){
        fetch("http://localhost:8080/TrainingWebMvcSpring2/roottypes/listAll.do")
            .then( (response) => {
                return response.json() })
                    .then( (json) => {
                        this.setState({data: json});
                    });
    }


    render () {
        console.log(data);

        return (
            <ReactGridLayout className="layout" cols={12} rowHeight={30} width={1200}>
                {this.state.data.map(function(item, key){
                    return(
                        <div>
                        <div key="a" data-grid={{x: 0, y: 0, w: 1, h: 2, static: true}}> {item}</div>
                        <div key="b" data-grid={{x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4}}> {item} </div>
                        <div key="c" data-grid={{x: 4, y: 0, w: 1, h: 2}}> {item} </div>
                        </div>
                    )
                })}
            </ReactGridLayout>
        )
    }
}

export default MyFirstGrid;

4 ответа

ReactJS: TypeError: this.state.data.map не является функцией?

Array#map доступно на массиве.

После получения вызова API,

this.setState({data: json});

json возвращая как объект, а не массив, который преобразует data к объекту

Измените это на:

this.setState({data: [...json]});

Поскольку ваша структура JSON выглядит следующим образом:

{
    array: [{},{},{}]
}

Итак, установка состояния таким образом решит вашу проблему: this.setState({data: json.array});,

Вы должны проверить, что вызов извлечения был успешным. Недостаточно добавить .catch() в конце цепочки обещаний (которую вы должны в любом случае) вы также должны проверить, что в результате успешного вызова был получен ответ OK вместо, например, 404. Например, например:

class MyFirstGrid extends React.Component {
    constructor() {
        this.state = {
            data: []
        }
    }

    componentDidMount(){
        fetch('http://localhost:8080/JiwayTrainingWebMvcSpring2/roottypes/listAll.do')
            .then( (response) => {
                if (response.ok) {
                    return response.json()
                } else {
                    throw new Error(`Fetch failed with code ${response.code}`)
                }
            })
            .then(json => {
                this.setState({data: json})
            })
            .catch(err => { console.log(`Something failed: ${err.message}`) };
    }

    render () {
        console.log(this.state.data);
        return (
            <ReactGridLayout className="layout" cols={12} rowHeight={30} width={1200}>
                {this.state.data.map(function(item, key){
                    return(
                        <div>
                        <div key="a" data-grid={{x: 0, y: 0, w: 1, h: 2, static: true}}> {item}</div>
                        <div key="b" data-grid={{x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4}}> {item} </div>
                        <div key="c" data-grid={{x: 4, y: 0, w: 1, h: 2}}> {item} </div>
                        </div>
                    )
                })}
            </ReactGridLayout>
        )
    }
}

export default MyFirstGrid

var data = [] это глобальный пустой массив. Я не вижу, чтобы вы присвоили его чему-либо еще, поэтому он всегда будет пустым массивом. Так console.log(data) является [], Просто не используйте это.

response.json() такой же как JSON.parse(response.text()), который возвращает объект или массив объектов. В вашем случае, так как нет map функция, я думаю, она возвращает объект.

Самый простой способ преобразовать объект в массив - это использовать Object.keys() функция.

const keys = Object.keys(json); // eg: json = {a: 1, b: 2}
const data = keys.map(key => json[key]); // eg: data = [1, 2]
this.setState({ data: data });

Поскольку вы не сообщили нам структуру своего ответа json, трудно дать конкретный ответ на вашу проблему.

Вот как проверить, является ли ответ массивом объектов:

if (json.length) { /* array */ } 
eles { /* object will return undefined, which is false */ }

Примечание: только что увидел ваш комментарий.this.setState({ data: json.array }) следует сделать.

  • Другая проблема в вашем коде constructor(props) { super(props); } props отсутствует в вашем классе constructor

Это должно помочь вам начать, не забывайте ключ при использовании функции карты

class MyFirstGrid extends React.Component {
  state = { data: [] };

  async componentDidMount() {
    try {
      const response = await fetch("http://localhost:8080/TrainingWebMvcSpring2/roottypes/listAll.do");
      const data = response.json().array;
      console.log(data, data.length);
      this.setState({
        data: data,
      });
    } catch (err) {
      console.error(err);
    } 
  }

  render() {
    const dataGrid = this.state.data.map((item, index) => (
      <div key={index}>
        <div key="a" data-grid={{x: 0, y: 0, w: 1, h: 2, static: true}}> {item}</div>
        <div key="b" data-grid={{x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4}}> {item} </div>
        <div key="c" data-grid={{x: 4, y: 0, w: 1, h: 2}}> {item} </div>
      </div>
    ));

    return(
      <ReactGridLayout className="layout" cols={12} rowHeight={30} width={1200}>
        {dataGrid}
      </ReactGridLayout>
    );
  }
}
Другие вопросы по тегам