我正在尝试将所有组件编写为纯函数,但现在我遇到了麻烦。我有一个看起来有点像下面的组件。麻烦的是,ajax请求的结果会导致重新呈现,这会导致另一个ajax请求,并且你有无限循环。如何妥善处理?
const PageProductFunnel = function (props) {
const agent = ajaxagent;
var list = [];
agent.get(`https://mylist.com/${productSKU}`).then((res) => {
list = res.data;
});
return (
<div>
<div className="cell">
<article className="article">
<h1 className="article-title">{product.name}</h1>
<FunnelStep {...props} list={list} />
<ButtonAddToCart product={product} />
</article>
</div>
</div>
);
};
答案 0 :(得分:1)
您可以采取的方法很少:
答案 1 :(得分:0)
您需要使用stateful
组件。
class PageProductFunnel extends React.Component {
state = {
"list": []
}
componentWillMount () {
agent.get(`https://mylist.com/${productSKU}`).then((res) => {
this.setState({list:res.data})
});
}
render () {
return (
<div>
<div className="cell">
<article className="article">
<h1 className="article-title">{product.name}</h1>
<FunnelStep {...props} list={this.state.list} />
<ButtonAddToCart product={product} />
</article>
</div>
</div>
);
}
};
答案 2 :(得分:0)
编辑请阅读评论。经过一些考虑后,我决定实施DavorinRuševljans的第一个建议。我自己的解决方案有效但他的更好。
感谢您的建议,但他们确实没有解决问题。到目前为止,我所有的代码都是纯粹的,我真的很想坚持下去。在全局范围内进行调用不会改变我的情况,因为响应仍会导致渲染。
我更改了代码,以便列表是状态的一部分(我正在使用redux)。仅当列表为空时,才执行ajax调用。每当我知道我期待新数据时,我会在页面呈现之前清除旧列表。
if (props.list.length === 0) {
agent.get(`https://mylist.com/${productSKU}`).then((res) => {
props.setList(res.data);
});
}
答案 3 :(得分:0)
进行Ajax调用的更好的生命周期挂钩是 componentDidMount ()。如果您对使用纯组件非常专一,则也可以在纯组件中使用。
class Sample extends PureComponent{
//react implement ShouldComponentUpdate for us which does shallow comparison
componentDidMount(){
//api call here
}
}
但是您不能仅使用pureComponent来构建React应用,因为如果您不想通过检查状态来停止更新生命周期,那么您就不能使用PureComponent来做到这一点,因为Pure组件仅对我们进行浅层检查,并检查组件中的所有状态。
我们应该在项目之间平衡有状态,PureComponent和无状态。