2015-11-07 56 views
1

我正在使用子上下文技術將上下文傳遞給應用程序的子節點。React-router:無法傳遞上下文

童上下文成功傳遞到頭組件,但不是在遭遇元器件。 任何想法來解決這個問題。 謝謝。

應用:

export default class Application extends React.Component { 
constructor(props, context){ 
    super(props); 
    this._onDataReceived=this._onDataReceived.bind(this); 
} 

componentDidMount() { 
PersonalStore._onDataReceived(this._onDataReceived); 
} 

componentWillUnmount() { 
PersonalStore._offDataReceived(this._onDataReceived); 
} 

getChildContext() { 
return { name:"Moussawi7" }; 
} 
renderRouter(){ 
ReactDOM.render((
    <Router> 
    <Route path="/" component={Encounter} /> 
    <Route path="inbox"> 
    <IndexRoute component={Inbox} onEnter={()=>this.refreshScroller()}/> 
    <Route path=":userID" component={Conversation} /> 
    </Route> 
    <Route path="*" component={NotFound} /> 
    </Router> 
),document.getElementById('content')); 
} 

render() { 
    return (
    <div className="container"> 
    <Header/> 
    <div id="content"></div> 
    </div> 
    ); 
} 
_onDataReceived() { 
    this.renderRouter(); 
} 
} 
Application.childContextTypes={ 
name: React.PropTypes.string.isRequired 
} 

頁眉:

export default class Header extends React.Component { 
    constructor(props,context) { 
    super(props,context); 
    console.log(context);// Object{name:"Moussawi7"} 
    } 
} 
Header.contextTypes= { 
     name: React.PropTypes.string.isRequired 
    } 

遭遇:

export default class Encounter extends React.Component { 
    constructor(props,context) { 
    super(props,context); 
    console.log(context);// Object {name:undefined} 
    } 
} 
Encounter.contextTypes= { 
     name: React.PropTypes.string.isRequired 
    } 
+1

爲什麼不直接在渲染方法中渲染路由器而不是在'componentDidMount'中單獨渲染? –

+0

@Morhaus,我的代碼比這個例子複雜得多,所以我一旦收到數據就開始路由。下面的答案解決了這個問題。謝謝。 – Moussawi7

+0

@ Morhaus,根據「componentDidMount」我已經更新了代碼。 – Moussawi7

回答

5

由於Morhause說,這很可能是你的問題。建議的方法是路由器是基本元素,應用程序包裝其他路線。在這裏,我換提供商路由器周圍,使一切有訪問提供商的背景:

// Provider.js Your app context provider 

import React, { Component, PropTypes, Children } from 'react' 

class Provider extends Component { 

    static childContextTypes = { 
     name: PropTypes.string 
    } 

    getChildContext() { 
     return { 
      name: 'Moussawi7' 
     }; 
    } 

    render() { 
     let { children } = this.props; 
     return Children.only(children); 
    } 
} 

// Router.js Your Provider+Router is the first thing rendered on the root, not Application, which is the base route 

ReactDOM.render(
    <Provider> 
     <Router> 
      <Route path='/' component={Application}> 
       <IndexRoute component={Encounter} /> 
       <Route path='users' component={Users} /> 
       <Route path="inbox"> 
        <IndexRoute component={Inbox} onEnter={()=>this.refreshScroller()}/> 
        <Route path=":userID" component={Conversation} /> 
       </Route> 
       <Route path="*" component={NotFound} /> 
      </Route> 
     </Router> 
    </Provider>, 
    document.getElementById('content') 
); 

// Your Application renders the child routes 

class Application extends Component { 

    render() { 
     return (
      <div> 
       <header> 
        <nav> 
         <ul> 
          <li><Link to='/'>Home</Link></li> 
          <li><Link to='/users'>Users</Link></li> 
         </ul> 
        </nav> 
       </header> 
       <div className='route-content'> 
        {this.props.children} 
       </div> 
      </div> 
     ) 
    } 
} 

注意我用ES7的static在那些需要巴貝爾0級,我相信例子,但是你可以把它們放在外面的類。

+2

你說得對,反應路由器應該是基本元素,但是我的代碼比我提供的例子複雜得多。一旦我收到數據,我需要開始渲染,否則我必須在每個組件中提供條件。謝謝,黃金答案:) – Moussawi7