Подтвердить что ты не робот

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 явно определяет всех детей, поэтому состояние передачи было естественным, но я не вижу, как это сделать сейчас.

4b9b3361

Ответ 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'))