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