2016-07-22 4 views
1

У меня проблема с запутанностью, которую я не могу понять. Я новичок, чтобы реагировать + flux + реагировать на маршрутизатор.React router передает определенные параметры дочерним компонентам

У меня есть следующие маршруты:

<Router history={browserHistory} > 
    <Route path="/" component={App}> 
     <IndexRoute component={Search}/> 
     <Route path="/login" component={Login} /> 
     <Route name="client" path="/client(/:clientid)" component={Client}/> 
     {/* <Route name="tel" path="/tel/:telid" component={Tel}/>*/} 
    </Route> 
</Router> 

Я хочу, чтобы иметь возможность передать конкретный Params к конкретным маршрутам. Я знаю, что могу передать все параметры во все маршруты, используя:

{this.props.children && React.cloneElement(this.props.children, {...})} 

Однако я не хочу разрешать доступ субкомпонентам к другим состояниям компонентов. В идеале я хотел бы передать loginState в компонент входа, searchState в компонент поиска и clientState для клиентского компонента. с указанным выше способом клиентский компонент может получить доступ ко всем состояниям компонентов.

настоящее время у меня этот обходной путь, но он чувствует себя грязным и не очень будущее доказательство:

var React = require('react'); 

var AppStore = require('../stores/AppStore'); 

var browserHistory = require('react-router').browserHistory; 

// Flux cart view 
var App = React.createClass({ 

    getInitialState() { 
     return AppStore.getState(); 
    }, 

    componentWillMount() { 
     if (!this.state.auth.loggedIn) { 
      browserHistory.push('/login'); 
     } 
    }, 
    // Add change listeners to stores 
    componentDidMount() { 
     AppStore.addChangeListener(this._onChange); 
    }, 

    // Remove change listers from stores 
    componentWillUnmount() { 
     AppStore.removeChangeListener(this._onChange); 
    }, 

    // Method to setState based upon Store changes 
    _onChange(){ 
     this.setState(AppStore.getState()); 
    }, 

    // Render cart view 
    render() { 
    console.log(this.props.children); 
    var name = this.props.children.type.displayName; 
    var p; 
    switch(name) { 
     case 'client': 
      p = {clientState: 'test'} 
     break; 
     case 'login': 
      p = {auth: this.state.auth} 
     break; 
    } 
    return (
     <div> 
      {this.props.children && React.cloneElement(this.props.children, p)} 
     </div> 
    ); 
    } 

}); 

module.exports = App; 

Любые мысли о том, как достичь этого правильно? Я просмотрел много результатов Google, но большинство из них вернулись к старым версиям реагирования и реагированию.

+0

Я надеюсь, что вы после этого есть [createElement] (https://github.com/reactjs/react-router/blob/master/docs/API.md#createelementcomponent-props) компонента «Router» –

+0

@ code-jaff спасибо за это - будучи новым, как wou ld я реализую это? это в главном контроллере приложения (основной маршрут), и я предполагаю, что это случай просто переопределения этой функции? не могли бы вы уточнить в ответе? – 4razmus

ответ

0

вы можете использовать named components

...  
<Route path="/login" components={{login:Login}} /> 
<Route path="/client(/:clientid)" components={{client:Client}}/> 
... 

И в App компоненте

class App extends Component { 
    constructor(props){ 
     super(props); 
     this.setProps= this.setProps.bind(this); 
    } 
    setProps(comp, props){ 
     if(!comp) return null; 
     return React.cloneElement(comp, props); 
    } 
    render(){ 
     const {client, login}=this.props; 
     const {clientData, loginData}=this.state; 

     return (<div> 
      {this.setProps(client,clientData)} 
      {this.setProps(login,loginData)} 
     </div>); 
    } 
} 

export default App; 

также ПОЛЕЗНЫЕ когда на странице более одного компонента для каждого маршрута

+0

пришлось изменить некоторые элементы, чтобы передать данные внутри объекта и преобразовать в модуль не ES6, но спасибо - все работает как ожидалось. – 4razmus

Смежные вопросы