不打扰读物的问题,有一个解决方案在年底渲染分量不火的componentDidMount
我有以下的路由器,使用反应路由器4
return (
<Router>
<Page>
<Route exact path="/" component={HomePage} />
<Route path="/courses/:courseName" component={CoursePage} />
</Page>
</Router>
);
的Page
组件看起来是这样的:
function Page(props) {
const { children } = props;
return (
<div className="page">
<SiteHeader />
{children}
<SiteFooter />
</div>
);
}
SiteHeader
,SiteFooter
,HomePage
和CoursePage
是纯粹的表现组分;他们把道具放在标签上。没有连接到一个redux商店或任何东西。 HomePage
和CoursePage
被定义为类。
Inside HomePage
and CoursePage
我需要使用componentDidMount
钩子才能与DOM交互。
现在下面奇怪的事情发生了:
STEP 1:我重新加载应用从/
网址
- 的
Page
渲染功能执行 - 的
HomePage
的构造函数执行 componentDidMount
HomePage
执行
STEP 2:我浏览到/courses/:courseName
- 的
Page
渲染功能执行 - 的
HomePage
的componentWillUnmount
执行 - 的
CoursePage
的构造函数执行
请注意CoursePage
的componentDidMount
如何不发射。这很重要,因为我需要componentDidMount
挂钩。
STEP 3:我导航回到/
从/courses/:courseName
- 的
Page
渲染功能执行 - 的
HomePage
的构造函数执行 - 的的
CoursePage
componentWillUnmount
执行 - 的
HomePage
的componentDidMount
执行
STEP 4:我导航回到/courses/:courseName
从/
再次
- 渲染的
Page
函数执行 - 的
componentWillUnmount
的HomePage
执行 - 的
CoursePage
的构造函数执行 - 的
CoursePage
的componentDidMount
执行
注意
- 如果在步骤1我已经从
/courses/:courseName
,而不是/
重载会发生同样的事情,而不是我把HomePage
放在CoursePage
的地方,反之亦然。 - 我总是失去STEP 2(第一个重定向)的
componentDidMount
。之后,所有componentDidMount
函数按预期正常激活。 - 请注意步骤3和步骤4中的粗体部分如何以相反顺序触发。我不确定这是否有意义。
问题
为什么在步骤2中的路线的
component
不火的componentDidMount
方法?我在这里错过了一些非常明显的东西,它是我不知道的一些奥术知识还是我遇到了一个错误?奖金:什么是与
CoursePage
的componentWillUnmount
前HomePage
射击类的构造函数处理,而当我们从导航到/
的/courses/:coursName
oposite是不是真的?
当你使用组件(而不是渲染,下同)的路由器使用 React.createElement从给定的 组件创建一个新的阵营元素。 这意味着如果你提供了一个内联函数,你是 每个渲染创建一个新的组件。这会导致现有的 组件取消安装,并且新的组件安装将更新现有组件,而不仅仅是 。
这使得我的问题,并提出甚至不及义
替代方法,我发现
在我Page
成分,如果我只需要移动children
的顺序是这样
function Page(props) {
const { children } = props;
return (
<div className="page">
{children} // MOVED FIRST
<SiteHeader />
<SiteFooter />
</div>
);
}
那么问题就解决了,但我认为这不是一个合适的解决方案。我真的很想知道发生了什么,因为它将我撕裂。
编辑:
问题被编辑为简洁和使用例场景简单
更新 - 进一步观察
让Stub.jsx
是以下组件
import React from 'react';
class Stub extends React.Component {
constructor(props) {
super(props);
debugger;
}
componentDidMount() { debugger; }
componentWillUnmount() { debugger; }
render() { return <div style={{ margin: '100px 0' }}><span>Hello</span></div>; }
}
export default Stub;
和MockPage.jsx
是以下组件
function MockPage(props) {
const { children } = props;
debugger;
return (
<div className="page">
<div>Hi</div> //Instead of SiteHeader
{children}
<div>Hi</div> //Instead of SiteFooter
</div>
);
}
以下配置然后都发挥正常,含义没有componentDidMount
呼叫重定向之间失去:
A)
return (
<Router>
<div>
<Route exact path="/" component={Stub} />
<Route path="/courses/:courseName" component={Stub} />
</div>
</Router>
);
B)
return (
<Router>
<MockPage>
<Route exact path="/" component={Stub} />
<Route path="/courses/:courseName" component={Stub} />
</MockPage>
</Router>
);
最终日期:
发现问题!
问题显然是react-addon-perf
,我正在使用一个按钮,我正在导入到我的SiteHeader
组件。 Perf工具在发生的第一次重定向时抛出了一个错误,这个错误搞砸了后续组件的生命周期钩子。这解释了一个事实,即当我将children
的位置移至SiteHeader
之前的所有工作。感谢任何懒得读我的动力和对不起浪费你的时间。
的'Page'部件仍然需要呈现它的孩子,所以'需要children'。无论如何,如你所建议的那样做,仍然会失去第一个'componentDidMount':/ –
感谢您试图提供帮助。原来,我的问题与我自己的实现有关(请参阅问题最底部的FINAL UPDATE),没有人可以在不阅读“SiteHeader”的实现的情况下找到它。仍然要把它标记为一个可以接受的答案,并为此付出努力。干杯。 –