2016-03-07 196 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')) 
相关问题