我的需求是:在同一页面URL发生改变时,获取URL中的参数,然后请求新的数据。
代码如下:
componentWillReceiveProps(props) {
const { id, tagName, articleNum } = props.match.params;
this.setState({
tagId: `,${id},`,
tagName,
articleNum,
}, () => {
this.getArticleByUserId();
});
}
这样就导致了死循环。为什么呢?随后找了一些componentWillReceiveProps勾子的资料如下:
当props发生变化时执行,初始化render时不执行,在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()来更新你的组件状态,旧的属性还是可以通过this.props来获取,这里调用更新状态是安全的,并不会触发额外的render调用。
通俗来说componentWillReceiveProps就是用来监听props的变化的。
然后闭眼冥思三秒发现导致他死循环的流程是这样的:前面跳过,到达componentWillReceiveProps函数,获取props中的值,然后setState(),setState并不会导致死循环,导致死循环的是发送请求,因为用了redux,后台响应的数据都会由redux来管理,而redux又是通过props来传递数据的,这样一来props发生了改变,那么就又进入了componentWillReceiveProps函数,这就是导致死循环的原因了。
那么改怎么破解呢?
既然原因找到了,那么破解方法就自然而然有了,很简单,就是标记法。
首先,第一次进入的时候,通过componentDidMount 在state中设置一个标记,随后每次在componentWillReceiveProps 中进行判断并更新标记。由于需求不同,解决方式也会有所差异。下面是我的解决代码:
// 首次进入查询
componentDidMount = () => {
const { id, tagName, articleNum } = this.props.match.params;
this.setState({
tagId: `,${id},`,
tagName,
articleNum,
}, () => {
this.getArticleByUserId();
});
};
// url 发生改变时且不同于上次则重新查询
componentWillReceiveProps(props) {
const { id, tagName, articleNum } = props.match.params;
if (tagName !== this.state.tagName) {
this.setState({
tagId: `,${id},`,
tagName,
articleNum,
}, () => {
this.getArticleByUserId();
});
}
}
问题解决!!!
如果有所不对或更简单的方法可以指出,毕竟我只是个半吊子前端(/ω\*)……… (/ω•\*)。
我的博客地址:http://ymyhome.cn/#/article/73