【发布时间】: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