2017-04-18 42 views
3

不打扰读物的问题,有一个解决方案在年底渲染分量不火的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> 
); 
} 

SiteHeaderSiteFooter,HomePageCoursePage是纯粹的表现组分;他们把道具放在标签上。没有连接到一个redux商店或任何东西。 HomePageCoursePage被定义为类。

Inside HomePage and CoursePage我需要使用componentDidMount钩子才能与DOM交互。

现在下面奇怪的事情发生了:

STEP 1:我重新加载应用从/网址

  • Page渲染功能执行
  • HomePage的构造函数执行
  • componentDidMountHomePage执行

STEP 2:我浏览到/courses/:courseName

  • Page渲染功能执行
  • HomePagecomponentWillUnmount执行
  • CoursePage的构造函数执行

请注意CoursePagecomponentDidMount如何不发射。这很重要,因为我需要componentDidMount挂钩。

STEP 3:我导航回到//courses/:courseName

  • Page渲染功能执行
  • HomePage的构造函数执行
  • 的的CoursePagecomponentWillUnmount执行
  • HomePagecomponentDidMount执行

STEP 4:我导航回到/courses/:courseName/再次

  • 渲染的Page函数执行
  • componentWillUnmountHomePage执行
  • CoursePage的构造函数执行
  • CoursePagecomponentDidMount执行

注意

  • 如果在步骤1我已经从/courses/:courseName,而不是/重载会发生同样的事情,而不是我把HomePage放在CoursePage的地方,反之亦然。
  • 我总是失去STEP 2(第一个重定向)的componentDidMount之后,所有componentDidMount函数按预期正常激活。
  • 请注意步骤3和步骤4中的粗体部分如何以相反顺序触发。我不确定这是否有意义。

问题

  • 为什么在步骤2中的路线的component不火的componentDidMount方法?我在这里错过了一些非常明显的东西,它是我不知道的一些奥术知识还是我遇到了一个错误?

  • 奖金:什么是与CoursePagecomponentWillUnmountHomePage射击类的构造函数处理,而当我们从导航到//courses/:coursName oposite是不是真的?

documentation

当你使用组件(而不是渲染,下同)的路由器使用 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之前的所有工作。感谢任何懒得读我的动力和对不起浪费你的时间。

回答

1

使用React-route 4,您可以撰写这样的页面。每条与路线相匹配的路线都将显示在视图中。该props.children不再需要与反应路线4.

这是代码是为我工作。 如果我转到'/',那么头部,主页和页脚都会呈现,包括DidMount。 如果我去“/场/ 1”当时的标题,网页,当然和页脚是使包括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> 
    ); 
    } 
} 
+0

的'Page'部件仍然需要呈现它的孩子,所以'需要children'。无论如何,如你所建议的那样做,仍然会失去第一个'componentDidMount':/ –

+0

感谢您试图提供帮助。原来,我的问题与我自己的实现有关(请参阅问题最底部的FINAL UPDATE),没有人可以在不阅读“SiteHeader”的实现的情况下找到它。仍然要把它标记为一个可以接受的答案,并为此付出努力。干杯。 –