我是react-router
的新用户,现在我的应用程序中有以下路线:
<Router history={browserHistory}>
<Route path="/" component={MainLayout}>
<Route path="/v/:username/:reponame/:page/:perPage" component={Results} />
</Route>
</Router>
如您所见,有一个MainLayout组件,其中包含一个<input type="text">
,用于连接到Github API并检索某个仓库的问题列表。
然后Results
组件介入。以下是componentDidMount()
的代码:
componentDidMount() {
const {
username,
reponame,
page,
perPage
} = this.props.params;
this.sendRequest(username, reponame, page, perPage);
}
sendRequests
本质上包含用于获取输出数据的ajax查询,之后它被设置为组件的状态:
this.state = {
data: [], // here
lastPage: -1,
errorMessage: ''
}
现在这种情况很有效,直到想要改变input
的值。
如我所见,Result
组件无法卸载。相反,它调用componentWillReceiveProps()
并更新现有组件。 AFAIK可以安全地在componentDidUpdate()
中执行旁边通话,因此我只是从componentDidMount()
复制了上面的代码并将其粘贴在那里。这样,虽然(并且绝对合理),componentDidMount()
被反复调用。
目前我提出的唯一解决方法是比较sendRequest()
本身的新旧数据,并在其内部调用setState()
时才会通过deep-equal
包进行调整,因此它看起来像这样:
if (!equal(res, this.state.data)) {
this.setState({
...this.state,
data: res,
lastPage
});
}
这被认为是一种好的模式还是有更好的方法来解决这个问题?
答案 0 :(得分:1)
您不应在cDM生命周期内使用setState。因为它可能会触发重新渲染,这会导致无限循环。
在组件装载后更新状态将触发第二次render()调用,并可能导致属性/布局颠簸。
https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md