React 在 render 方法中调用一个函数会导致无限的调用堆栈
React calling a function inside the render method leads to endless call stack
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;
在此示例中,我在 render()
方法内部调用 func()
,它会导致类似于 Whosebug 的结果,只是不会停止调用它。无论如何要解决这个问题?我真的没有找到任何解决方案。如果我说只是在渲染器内部做一个 for 循环,它会按预期工作,它只被调用一次,那么为什么这个函数被调用了无数次
你永远不应该 setstate
在渲染中,而是在 life cycle methods, in your case because you are doing an ajax request you should do that in componentDidMount
link
之一中进行渲染
您必须通常在 componentDidMount
内拨打 ajax
电话。它看起来像下面
componentDidMount() {
this.func();
}
在您的 ajax
通话中,一旦您收到回复,请将其设置为状态。所以你的 func
看起来像下面这样
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,
});
});
}
您的 render
将使用状态中的数据并适当地呈现所需的 DOM 结构。
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>
)
}
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;
在此示例中,我在 render()
方法内部调用 func()
,它会导致类似于 Whosebug 的结果,只是不会停止调用它。无论如何要解决这个问题?我真的没有找到任何解决方案。如果我说只是在渲染器内部做一个 for 循环,它会按预期工作,它只被调用一次,那么为什么这个函数被调用了无数次
你永远不应该 setstate
在渲染中,而是在 life cycle methods, in your case because you are doing an ajax request you should do that in componentDidMount
link
您必须通常在 componentDidMount
内拨打 ajax
电话。它看起来像下面
componentDidMount() {
this.func();
}
在您的 ajax
通话中,一旦您收到回复,请将其设置为状态。所以你的 func
看起来像下面这样
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,
});
});
}
您的 render
将使用状态中的数据并适当地呈现所需的 DOM 结构。
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>
)
}