Reputation: 667
I am making my first steps with react and I'm struggling with the error message:
this.state.items.map is not a function
I already know that map is only a member of an array but not of objects. In the constructor of my App-class I initialized items[] explicit to an array.
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class HelloComponent extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
class App extends Component {
constructor() {
super();
this.state = { items: [] };
}
componentDidMount() {
fetch(`http://example.com/api`)
.then(result => {
this.setState({ items: result.json() });
}
);
}
render() {
var listItems = this.state.items.map(item => <HelloComponent name={item.name} />); // crash!!!
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
{listItems}
</p>
</div>
);
}
}
export default App;
I don't know what happens. I have the suspicion that the call to result.json() may override my array with an promise but I have no idea how to implement it correctly.
Upvotes: 0
Views: 1150
Reputation: 351
i suggest you a way to achieve your goal
import request from 'request' // obtain by npm install --save request
class App extends Component {
constructor() {
super();
this.state = { items: [] };
}
componentDidMount() {
request(`http://example.com/api`, (error, response, body) => {
this.setState({ items: JSON.parse(body) };
});
}
render() {
var listItems = this.state.items.map(item => <HelloComponent name=
{item.login} />); // worked!!!
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
{listItems}
</p>
</div>
);
}
}
Upvotes: 1
Reputation: 21694
I think your json
response is the one overwriting the regular array, you should setState only from inside the json promise:
fetch(`http://example.com/api`)
.then(result => {
result.json().then(json => this.setState({ items: json }))
}
);
Or, if you can support async/await, you can just await the result:
fetch(`http://example.com/api`)
.then(result => {
this.setState({ items: await result.json() })
}
);
Upvotes: 2