不要再阅读问题,最后有解决方案
我有以下路由器,使用 react-router 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
被定义为类。
在HomePage
和CoursePage
内部,我需要使用componentDidMount
挂钩,以便与DOM进行交互。
现在发生了以下奇怪的事情:
第1步:我从/
网址重新加载应用
Page
的渲染功能执行HomePage
的构造函数执行componentDidMount
的{{1}}执行 第2步:我导航至HomePage
/courses/:courseName
的渲染功能执行Page
的{{1}}执行componentWillUnmount
的构造函数执行 请注意HomePage
的{{1}}如何解除。这很重要,因为我需要CoursePage
挂钩。
第3步:我从componentDidMount
CoursePage
componentDidMount
的渲染功能执行/
的构造函数执行 /courses/:courseName
Page
执行 HomePage
的{{1}}执行 第4步:我再次从componentWillUnmount
导航回CoursePage
componentDidMount
的渲染功能执行HomePage
/courses/:courseName
执行 /
的构造函数执行 Page
的{{1}}执行备注
componentWillUnmount
而不是HomePage
重新加载,而不是在CoursePage
componentDidMount
重新加载CoursePage
,那么会发生同样的事情反之亦然。/courses/:courseName
(第一次重定向)。之后,所有/
函数都会按预期正常启动。问题
为什么在第2步中,路线HomePage
不会触发CoursePage
方法?我错过了一些非常明显的东西,是不是神秘的知识我不知道或是否遇到过错误?
Bonus :在componentDidMount
componentDidMount
之前component
触发的构造函数有什么处理,而对位不是真的当我们从componentDidMount
导航到HomePage
?
当您使用路由器使用的组件(而不是渲染,下面)时 React.createElement从给定的创建一个新的React元素 零件。 这意味着如果您提供内联函数,那么您就是 每次渲染都创建一个新组件。这导致了现有的 组件卸载和新组件安装而不仅仅是 更新现有组件。
这让我的问题变得毫无意义
我找到的替代方法
在我的componentWillUnmount
组件中,如果我只是按这样移动CoursePage
的顺序
/
然后问题得到解决,但我认为这不是一个合适的解决方案。我真的很想知道发生了什么,因为它撕裂了我。
编辑:
为简洁起见,编辑了该问题并使用例场景更简单
更新 - 进一步观察
让/courses/:coursName
成为以下组件
Page
和children
是以下组件
function Page(props) {
const { children } = props;
return (
<div className="page">
{children} // MOVED FIRST
<SiteHeader />
<SiteFooter />
</div>
);
}
然后,所有以下配置都能正常播放,表示重定向之间没有Stub.jsx
来电丢失:
A)
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;
B)
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
。 Perf工具在发生的第一个重定向上抛出了一个错误,这个错误正在弄乱随后组件的生命周期钩子。这解释了这样一个事实:当我在return (
<Router>
<div>
<Route exact path="/" component={Stub} />
<Route path="/courses/:courseName" component={Stub} />
</div>
</Router>
);
之前移动return (
<Router>
<MockPage>
<Route exact path="/" component={Stub} />
<Route path="/courses/:courseName" component={Stub} />
</MockPage>
</Router>
);
的位置时,一切正常。感谢所有为阅读我的烦恼而烦恼的人,以及抱歉因为浪费你的时间。
答案 0 :(得分:1)
使用React-route 4,你可以像这样编写页面。匹配路线的每条路线都将显示在视图中。 React-route 4不再需要props.children。
这是代码对我有用。 如果我去&#39; /&#39;然后标题,主页和页脚呈现包括DidMount。 如果我去&#39; / courses / 1&#39;然后标题,主页,课程和页脚是渲染,包括DidMount
import { BrowserRouter as Router, Route } from 'react-router-dom';
import React, { PropTypes } from 'react';
import SiteFooter from './components/App/siteFooter'
import SiteHeader from './components/App/siteHeader'
import CoursePage from './components/App/coursePage'
import HomePage from './components/App/homePage'
export default class Routes extends React.Component {
render() {
return (
<Router>
<div>
<Route path="/" component={SiteHeader} />
<Route path="/" component={HomePage} />
<Route path="/courses/:courseName" component={CoursePage} />
<Route path="/" component={SiteFooter} />
</div>
</Router>
);
}
}