ReactJS: TypeError: this.state.data.map is not a function

邮差的信 提交于 2019-12-11 05:59:33

问题


-Can someone please help me with this. I am getting an error described in the title of this question. I want to put JSON data inside react-grid-layout component. This library can be found on (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;

回答1:


ReactJS: TypeError: this.state.data.map is not a function?

Array#map is available on array.

After fetch API call ,

this.setState({data: json});

json returning as an object and not an array which converting data to an object

Change this to :

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



回答2:


Since your JSON structure is as follows:

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

So, setting state this way will solve your issue: this.setState({data: json.array});.




回答3:


var data = [] is a global empty array. I don't see you assign it to anything else, so it will always be a empty array. So console.log(data) is []. Just don't use it.

response.json() is same as JSON.parse(response.text()), which returns a object, or an object array. In your case, since there is no map function, I guess it returns an object.

The easiest way to transform an object to an array is to use Object.keys() function.

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

Since you haven't tell us the structure of your json response, it is hard to provide a specific answer to your problem.

This is how to test if response is array of object:

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

Note: Just saw your comment. this.setState({ data: json.array }) should do.

  • Another problem in your code is constructor(props) { super(props); } The props is missing in your class constructor

This should get you started, don't forget the key, when using map function

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



回答4:


You should be checking that the fetch call was successful. It's not enough to add a .catch() at the end of the promise chain (which you should anyway), you must also check that the successful call returned an OK response instead of, for example, a 404. Like this, for example:

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


来源:https://stackoverflow.com/questions/48900899/reactjs-typeerror-this-state-data-map-is-not-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!