Reputation: 157
componentDidMount() {
$.ajax({
type: 'post',
url: 'requests.php',
data: {requestKey: "hello"}
}).done(function(data){
this.setState({
items: data
});
}.bind(this));
}
render(){
let items = this.state.items;
console.log(items);
return(
<div id="tops">
<h1 className="header">
What's top!
<a href="#" className="more">more!</a>
</h1>
{items.map(function(item){
return(
<TopsItem
img={item.img}
heading={item.heading}
desc={item.desc}
/>
);
})}
</div>
);
}
The data in state.items does not effect the components in map function. And yet I get this error:
items.map is not a function
console.log(items);
works after 1sec.
At first it's empty, then it gets the data in it.
Upvotes: 1
Views: 199
Reputation: 112787
You need a default value for your items
so that it will work until your network request has finished.
You also need to make sure that you parse the JSON string in the response of your network request.
Example
class MyComponent extends React.Class {
state = { items: [] };
componentDidMount() {
$.ajax({
type: 'post',
url: 'requests.php',
data: {requestKey: "hello"}
}).done(function(data){
this.setState({
items: JSON.parse(data)
});
}.bind(this));
}
render() {
// ...
}
}
Upvotes: 0
Reputation: 156
Reason
JavaScript's map
function works with an array, and initially this.state.items
are undefined until it gets response from ajax request.
the component get rendered before the response comes from ajax and it throws the error
Solution
Here we can set the initial state value {items:[]}
, it must be an array, so it could execute the map()
any without error.
class MyComponent extends React.Class {
constructor(props) {
this.state = {
items: []
};
}
}
Upvotes: 0
Reputation: 5546
initial render needs your items array to be present in state of your component.
You should initialise items in constructor like this
this.state = {
items = []
}
Upvotes: 1