2016-03-07 191 views
24

我第一次使用React-router,但我不知道如何去思考它。以下是我如何在嵌套路由中加載組件。React路由器和this.props.children - 如何將狀態傳遞給this.props.children

切入點.js文件

ReactDOM.render(
    <Router history={hashHistory} > 
     <Route path="/" component={App}> 
      <Route path="models" component={Content}> 
     </Route> 
    </Router>, 
    document.getElementById('app') 
); 

App.js

render: function() { 
    return (
     <div> 
     <Header /> 
     {this.props.children} 
     </div> 
    ); 
    } 

所以我的應用程序的孩子是我送的內容的組成部分。我使用的流量和我App.js具有狀態並監聽更改,但我不知道如何將該狀態傳遞給this.props.children。在使用react-router之前,我的App.js明確定義了所有的孩子,所以傳遞狀態是很自然的,但我現在不知道該怎麼做。

+1

的可能的複製[如何通過道具{this.props.children}](http://stackoverflow.com/questions/32370994/how-to-pass-props-to-this-props-孩子) –

回答

27

使用幾個陣營輔助方法,您可以添加狀態,道具和其他任何對this.props.children

render: function() { 
    var children = React.Children.map(this.props.children, function (child) { 
    return React.cloneElement(child, { 
     foo: this.state.foo 
    }) 
    }) 

    return <div>{children}</div> 
} 

然後你的孩子組件可以通過道具訪問此,this.props.foo

+0

是的,我正在讀關於孩子的幫手,看到了這一點。爲什麼使用Map而不是ForEach? – Patrick

+1

一般建議不要改變數據,如果你可以幫助它。一般來說,這是編程的好習慣,而不僅僅是React。只有在沒有其他可能的解決方案時纔會發生突變---這是罕見的情況。 – azium

+0

我同意突變,但我想我沒有看到連接 - ForEach是否必然會突變狀態? – Patrick

10

您可以使用React method "cloneElement"來完成此操作。當你克隆元素時,你可以在那個時候傳遞道具。在渲染fn中使用克隆而不是原始文件。例如:

render: function() { 
    var childrenWithProps = React.cloneElement(this.props.children, {someProp: this.state.someProp}); 
    return (
     <div> 
     <Header /> 
     {childrenWithProps} 
     </div> 
    ); 
    } 
+0

'childrenWithProps'周圍丟失花括號' – azium

+0

當this.props.children只有一個元素時,您的示例是否會克隆所有孩子或只有一個?我在stackoverflow上看到了另一個例子,但似乎我錯誤的是需要手動遍歷它們來完成基本的道具傳遞。 – Patrick

+1

@Patrick如果你看看我的答案,你會首先注意到'Children.map'。這是必需的,通常是因爲'children'可以是一個對象或一個數組,在後一種情況下,你可以克隆每個元素。 – azium

2

還有使用Context的選項。 React-Router依靠它來訪問路由組件中的Router對象。

從另一個answer我介紹了一個類似的問題:

我趕緊把一起使用的codepen上下文的例子。 MainLayout定義了兒童使用上下文可以使用的一些屬性:userswidgets。這些屬性由UserListWidgetList組件使用。請注意,他們需要從contextTypes對象的上下文中定義他們需要訪問的內容。

var { Router, Route, IndexRoute, Link } = ReactRouter 

var MainLayout = React.createClass({ 
    childContextTypes: { 
    users: React.PropTypes.array, 
    widgets: React.PropTypes.array, 
    }, 
    getChildContext: function() { 
    return { 
     users: ["Dan", "Ryan", "Michael"], 
     widgets: ["Widget 1", "Widget 2", "Widget 3"] 
    }; 
    }, 
    render: function() { 
    return (
     <div className="app"> 
     <header className="primary-header"></header> 
     <aside className="primary-aside"> 
      <ul> 
      <li><Link to="/">Home</Link></li> 
      <li><Link to="/users">Users</Link></li> 
      <li><Link to="/widgets">Widgets</Link></li> 
      </ul> 
     </aside> 
     <main> 
      {this.props.children} 
     </main> 
     </div> 
    ) 
    } 
}) 

var Home = React.createClass({ 
    render: function() { 
    return (<h1>Home Page</h1>) 
    } 
}) 

var SearchLayout = React.createClass({ 
    render: function() { 
    return (
     <div className="search"> 
     <header className="search-header"></header> 
     <div className="results"> 
      {this.props.children} 
     </div> 
     <div className="search-footer pagination"></div> 
     </div> 
    ) 
    } 
}) 

var UserList = React.createClass({ 
    contextTypes: { 
    users: React.PropTypes.array 
    }, 
    render: function() { 
    return (
     <ul className="user-list"> 
     {this.context.users.map(function(user, index) { 
      return <li key={index}>{user}</li>; 
     })} 
     </ul> 
    ) 
    } 
}) 

var WidgetList = React.createClass({ 
    contextTypes: { 
    widgets: React.PropTypes.array 
    }, 
    render: function() { 
    return (
     <ul className="widget-list"> 
     {this.context.widgets.map(function(widget, index) { 
      return <li key={index}>{widget}</li>; 
     })} 
     </ul> 
    ) 
    } 
}) 

var Routes = React.createClass({ 
    render: function() { 
    return <Router> 
     <Route path="/" component={MainLayout}> 
      <IndexRoute component={Home} /> 
      <Route component={SearchLayout}> 
      <Route path="users" component={UserList} /> 
      <Route path="widgets" component={WidgetList} /> 
      </Route> 
     </Route> 
     </Router>; 
    } 
}) 

ReactDOM.render(<Routes/>, document.getElementById('root')) 
相關問題