【问题标题】:React: is componentDidUpdate same for 2 different instances of a component?React:组件的 2 个不同实例的 componentDidUpdate 是否相同?
【发布时间】:2018-01-15 20:29:16
【问题描述】:

我正在使用 react-router v4 编写一个 React (ES6, v16) (typescript) 应用程序。我正在观察一个非常奇怪的行为。这是我的渲染代码(非常简化):

render() {
   <Switch>

      <Route
         path="/foo/add"
         render={ props => {
                return (
                   <FormEntry title="add new" />
                );
         }}
      />

      <Route
         path="/foo/edit/:id"
         render={ props => {
                 return (
                    <FormEntry title="edit item" />
                 );
         }}
      />
   </Switch>
}

这里是 FormEntry 组件(简化版):

class FormEntry extends React.Component< { title: string }, any > {
    render() {
       return (
          <div>
             {this.props.title}
          </div>
       );
    }

    componentDidMount() {
       // code goes here
    }

    componentDidUpdate() {
       // code goes here
    }
}

现在,当我在应用程序中单击链接“/foo/add”时,第一个“Route”组件中的处理程序被触发(如预期的那样)并安装了组件“FormEntry”。方法 componentDidMount 被正确地触发了。

现在我点击链接“foo/edit/1”。第二个 Route 的处理程序被触发。

这一次,在“FormEntry”组件内部,没有触发生命周期方法“componentDidMount”,而是调用了“componentDidUpdate”方法。但这显然是正在安装的 FormEntry 的不同“实例”。我期待看到生命周期方法的开始......

我的应用程序中似乎只有一个“FormEntry”实例。那么为什么在第二种情况下(当 url "foo/edit:id" 的路由处理程序时)这个实例没有经过所有生命周期方法??

这是 v16 版本的 React 的重大变化吗? (我在以前版本的 react 中没有观察到这种行为)。

我们将非常感谢您的洞察力

【问题讨论】:

  • 但这显然是正在挂载的 FormEntry 的不同“实例”,是什么让它对你来说如此明显的不同实例? ;) 这是同一个实例
  • 嗯,我就是这么想的。我缩小了这个问题的范围(如果我可以称之为问题)。它与反应路由器有关。当我在 Route 组件之外使用 FormEntry 时,它会按预期工作,这意味着每次安装组件时,都会调用完整的生命周期方法
  • 另外,当我使用封装在“withRouter”HOC 函数中的 FormEntry 时,再次调用完整的生命周期方法......我不明白这种行为。这当然是设计使然...我将不得不进行进一步的研究。现在我将使用它们包裹在“withRouter”函数中

标签: javascript reactjs lifecycle


【解决方案1】:

&lt;Switch&gt; 检查上一个匹配路由的JSX 并将其与下一个路由的新JSX 进行比较。

如果匹配,它将使用它并且只更新更改的值而不重新安装组件。

否则它将创建新的反应元素并实例化新的组件。

在这里查看:https://github.com/ReactTraining/react-router/pull/4592

对此的一个转变是使用如下关键属性:

render() {
   <Switch>

      <Route
         path="/foo/add"
         render={ props => {
                return (
                   <FormEntry key="1" title="add new" />
                );
         }}
      />

      <Route
         path="/foo/edit/:id"
         render={ props => {
                 return (
                    <FormEntry  key="2" title="edit item" />
                 );
         }}
      />
   </Switch>
}

【讨论】:

    猜你喜欢
    • 2019-03-12
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    • 2022-01-10
    • 2023-03-23
    相关资源
    最近更新 更多