Reputation: 113
import React, {Component} from 'react'
import ajax from '../confing/ajax'
import $ from 'jquery'
class Categories extends Component {
constructor(props) {
super(props);
this.state = {
isActive: '',
categories: ''
};
this.switchLinkToActive = this.switchLinkToActive.bind(this);
}
switchLinkToActive(event) {
event.preventDefault();
let temp = [];
console.log(event.target.id);
for (let i = 0; i < this.state.isActive.length; i++) {
if (i === parseInt(event.target.id)) {
temp[i] = true;
} else {
temp[i] = false;
}
}
this.setState({
isActive: temp
})
}
func() {
let categories = [];
ajax.request.get('categories').then((resp) => {
let isActive = new Array(resp.length);
for (let i = 0; i < resp.length; i++) {
isActive[i] = false;
}
this.setState({
isActive: isActive
});
for (let i = 0; i < resp.length; i++) {
let element = resp[i];
categories.push(<a key={element.id} href=""
className={this.state.isActive[i] === true ? "list-group-item list-group-item-action active" : "list-group-item list-group-item-action"}
id={i} onClick={this.switchLinkToActive}>{element.name}</a>);
}
this.setState({
categories: categories
});
});
}
render() {
this.func();
return (
<div className="list-group col-3">
{/*{this.state.categories}*/}
<a key={2} href=""
className={this.state.isActive[2] === true ? "list-group-item list-group-item-action active" : "list-group-item list-group-item-action"}
id={2} onClick={this.switchLinkToActive}>Custom lemenet</a>
</div>
)
}
}
export default Categories;
in this example i am calling func()
inside of the render()
method and it leads to something similar to stackoverflow, it just doesn't stop calling it. Anyway to fix that? I didn't really find any solutions to that. If i lets say just do a for loop inside of the render it works as intended it's called only once, so why is the function called endless amount of times
Upvotes: 1
Views: 908
Reputation: 9418
You have to make your ajax
calls usually in componentDidMount
. It would look something like below
componentDidMount() {
this.func();
}
In your ajax
calls, once you get your response, set it to state. So your func
would look something like below
func() {
let categories = [];
ajax.request.get('categories').then((resp) => {
for (let i = 0; i < resp.length; i++) {
resp[i].isActive = false;
}
this.setState({
data : resp,
});
});
}
Your render
would use the data in state and render the required DOM structure appropriately.
render() {
return (
<div className="list-group col-3">
{
(this.state.data || []).map((element, idx) =>
categories.push(<a key={element.id} href=""
className={element.isActive ? "list-group-item list-group-item-action active" : "list-group-item list-group-item-action"}
id={idx} onClick={this.switchLinkToActive}>{element.name}</a>);
})
}
<a key={2} href=""
className={this.state.isActive[2] === true ? "list-group-item list-group-item-action active" : "list-group-item list-group-item-action"}
id={2} onClick={this.switchLinkToActive}>Custom lemenet</a>
</div>
)
}
Upvotes: 0
Reputation: 31024
You should never ever setstate
inside render, instead do it in one of the life cycle methods, in your case because you are doing an ajax request you should do that in componentDidMount
link
Upvotes: 1