无限componentDidUpdate()使用react-router调用

时间:2017-03-22 08:04:58

标签: reactjs react-router

我是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
        });
    }

这被认为是一种好的模式还是有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

您不应在cDM生命周期内使用setState。因为它可能会触发重新渲染,这会导致无限循环。

  

在组件装载后更新状态将触发第二次render()调用,并可能导致属性/布局颠簸。

     

https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md