2016-02-24 27 views
0

在此处反应新手。我很难过。我有一个主类,它有一个Header区域和一个Body区域。标题区域具有导航链接以下载不同类别的JSON。在启动时,随机柱插入身体:反应 - 使用React-Router LINK标记会导致父级重新渲染

var React = require('react'); 
var Header = require('./header'); 
var PostRandom = require('./post-random'); 

module.exports = React.createClass({ 
    render: function(){ 
     console.log("MAIN.render"); 
     return <div> 
      <Header /> 
      {this.content()} 

     </div> 
    }, 
    content: function(){ 
     console.log("MAIN.content"); 
     if(this.props.children){ 
      return this.props.children 
     }else{ 
      return <PostRandom /> 
     } 
    } 
}); 

这里的标题:

var React = require('react'); 
var Router = require ('react-router'); 
var Link = Router.Link; 
var categories = { 
    cats: [{ 
     name: 'Writing', 
     id: 10 
     }, 
     { 
     name: 'Essays', 
     id: 15 
     }, 
     { 
     name: 'Poetry', 
     id: 23 
     } 
     ] 
    }; 

module.exports = React.createClass({ 
    getInitialState: function(){ 
     console.log("HEADER.getInitialState") 
     return { 
      topics: categories.cats, 
     } 
    }, 
    render: function(){ 
     console.log("HEADER.RENDER"); 
     return <nav className="navbar navbar-static-top"> 
       <div className="container-fluid"> 
        <IndexLink to="/" className = "navbar-brand"> 
         Home 
        </IndexLink> 
        <ul className = "nav navbar-nav navbar-right"> 
         {this.renderTopics()} 
        </ul> 
       </div> 
      </nav> 
    }, 
    renderTopics: function(){ 
     console.log("HEADER: renderTopics") 
     return this.state.topics.slice(0,8).map(function(topic){ 
      return <li > 
       <Link activeClassName="active" to={"topics/" + topic.id}> 
        {topic.name} 
       </Link> 
      </li> 
     }); 
    } 
}); 

当我点击任何标题的链接,通过路由,它加载主题,并将它正确的主题ID。 Topic中的componentWillReceiveProps然后调用一个商店,下载该主题的帖子列表。这一切工作正常。路由器是非常简单的:

<Route path="/" component = {Main}> 
    <Route path="topics/:id" component = {Topic} /> 
</Route> 

的问题:出于某种原因,超出了我的构想,主要是重新呈现在我头上链接点击每次。这导致标题重新呈现,这使得主题重新呈现,这导致第二次调用存储。我不明白。控制台输出如下所示:

MAIN.render 
MAIN.content 
HEADER.RENDER 
HEADER: renderTopics 
TOPIC: componentWillReceiveProps 
TOPIC: render 
TOPIC:renderPosts 
MAIN.render 
MAIN.content 
HEADER.RENDER 
HEADER: renderTopics 
TOPIC: componentWillReceiveProps 
TOPIC: render 
TOPIC:renderPosts 
STORE: triggerChange 
TOPIC:onChange 
TOPIC: render 
TOPIC:renderPosts 
STORE: triggerChange 
TOPIC:onChange 
TOPIC: render 
TOPIC:renderPosts 

紧接着主题的初始呈现之后,主要调用再次呈现!这导致主题获得两次加载,并且两次调用componentWillReceiveProps,因此两次到达商店。我最终下载了两次JSON,并获得两个不同的随机数组。我看到一个随机帖子的初始列表,然后它被第二个随机的帖子列表所取代。啊。

如果我重新加载页面,留在同一主题中,Main不会被称为第二次 - 所以这是关于点击导致重新渲染的链接。下面是一个重载的控制台输出:

MAIN.render 
MAIN.content 
HEADER.getInitialState 
HEADER.RENDER 
HEADER: renderTopics 
TOPIC: getInitialState 
TOPIC: componentWillMount 
TOPIC: render 
TOPIC:renderPosts 
58 STORE: triggerChange 
TOPIC:onChange 
TOPIC: render 
TOPIC:renderPosts 

也很有趣:如果我更改链接标签只是回到主页面 - 也就是说,不调用/渲染主题的话 - 像这样:

<Link activeClassName="active" to={"/"}> 

主仍然得到重新渲染,重新渲染标题!控制台输出:

MAIN.render 
MAIN.content 
HEADER.RENDER 
HEADER: renderTopics 

所以它无关什么主题的推移,或来电来店 - 链接标签,点击后,使得它的父组件重新呈现!我确信我一定在做错事 - 但是什么?感谢您提供的任何见解/帮助!

回答

0

渲染不应该引发副作用。如果您发现自己试图控制render被调用的时间,那么您将走错路。

当路径匹配时,路由会呈现,只有在写入shouldComponentUpdate时,路由才会被重新渲染 - 但不要使用它来解决当前问题。

取代componentWillReceiveProps中的数据,它应该发生在componentWillMount

+0

1.我没有试图在调用渲染时“控制” - 它根本没有意义,它根本就没有被调用。 2.我不得不使用componentWillReceiveProps,因为当用户单击主题链接时,组件会使用新的JSON进行更新。 好消息:我(无意中)(主要)通过解决另一个问题 - 消除“垃圾”网址来解决问题。我添加了一个历史参数给路由器(以摆脱“垃圾”的URL),我不再得到双渲染! (加我的网址看起来不错...) –