React:componentDidUpdate对于组件的2个不同实例是否相同?

The*_*oul 5 javascript lifecycle reactjs

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

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>
}
Run Code Online (Sandbox Code Playgroud)

这是FormEntry组件(简化):

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

    componentDidMount() {
       // code goes here
    }

    componentDidUpdate() {
       // code goes here
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当在应用程序内部单击链接"/ foo/add"时,将触发第一个"Route"组件中的处理程序(按预期方式)并安装组件"FormEntry".正确触发方法componentDidMount.

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

这次,在"FormEntry"组件内部,未触发生命周期方法"componentDidMount",调用方法"componentDidUpdate".但这是正在安装的FormEntry的另一个"实例".我期待看到生命周期方法开始......

看起来我的应用程序中只有一个"FormEntry"实例.那么为什么在第二种情况下(当url的路由处理程序为"foo/edit:id"时)这个实例不会通过所有生命周期方法?

这是Re16的v16版本的重大变化吗?(我在之前版本的反应中没有观察到这种行为).

非常感谢您的见解

Bad*_*bet 2

<Switch>检查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>
}
Run Code Online (Sandbox Code Playgroud)