React router и this.props.children - как передать состояние this.props.children
Я использую React-router в первый раз, и я не знаю, как думать в нем еще. Вот как я загружаю свои компоненты во вложенные маршруты.
точка входа .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>
);
}
Итак, дочерний элемент моего приложения - это компонент контента, который я отправил. Я использую Flux, и у моего App.js есть состояние и прослушивание изменений, но я не знаю, как передать это состояние до этого. props.children. Перед использованием response-router мой App.js явно определяет всех детей, поэтому состояние передачи было естественным, но я не вижу, как это сделать сейчас.
Ответы
Ответ 1
Используя пару вспомогательных методов React, вы можете добавить состояние, реквизиты и все остальное в 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
.
Ответ 2
Для этого вы можете использовать метод React метод cloneElement. Когда вы клонируете элемент, в это время вы можете пройти в реквизитах. Используйте клон вместо оригинала в рендере fn. например:
render: function() {
var childrenWithProps = React.cloneElement(this.props.children, {someProp: this.state.someProp});
return (
<div>
<Header />
{childrenWithProps}
</div>
);
}
Ответ 3
Также существует возможность использования Context. React-Router полагается на это, чтобы предоставить доступ к объекту Router в компонентах маршрута.
Из другого ответа я дал аналогичный вопрос:
Я быстро собрал пример, используя контексты на codepen. MainLayout
определяет некоторые свойства, которые могут использоваться дочерними элементами в контексте: users
и widgets
. Эти свойства используются компонентами UserList
и WidgetList
. Обратите внимание, что им нужно определить, что им нужно для доступа из контекста в объекте 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'))