2017-04-27 23 views
1

我使用流星與之反應,路由器和我有以下代碼:陣營,路由器通過主要和側邊欄組件之間的道具

Routes.jsx:

Meteor.startup(() => { 
    render(
    <Router history={browserHistory}> 
     <Route path='/' component={App}> 
     <IndexRoute components={{ main: SelectTable, sidebar: MenuBar }} /> 
     <Route path='/DisplayTable/:tableId' 
      components={{ main: DisplayTable, sidebar: MenuBar }} /> 
     </Route> 
     <Route path='*' component={NotFound} /> 
    </Router>, 
    document.getElementById('react-root')); 
}); 

App.jsx :

export class App extends Component { 
    render() { 
    // if there's only one child logic here, irrelevant 
    return (
     <div className='container'> 
     <div className="Main"> 
      {this.props.main} 
     </div> 
     <div className="Sidebar"> 
      {this.props.sidebar} 
     </div> 
     </div>); 
    } 
} 

DisplayTable分量聽s到流星訂閱數據庫,並最終獲得這些屬性:

DisplayTable.propTypes = { 
    tableId: PropTypes.string.isRequired, 
    loading: PropTypes.bool.isRequired, 
    rows: PropTypes.array.isRequired, 
    cols: PropTypes.array.isRequired, 
    user: PropTypes.object, 
}; 

而且我菜單欄組件呈現這樣的:

<li><InsertRow tableId={this.props.params.tableId}/></li> 

的InsertRow具有這些屬性

InsertRow.propTypes = { 
    rows: PropTypes.array, 
    tableId: PropTypes.string, 
}; 

其中InsertRow和的行屬性完全一樣。

如何將屬性從主要組件傳遞到側邊欄,以便我可以將它傳遞給組件?

  • 也許一些與React.cloneElement雖然我是不是真的能夠環繞一個我的頭...
  • 我看了所有的mainsidebar的屬性,似乎我不能找到有用的東西......

變通:

  • 我理論上可以訂閱,並再次得到數據,因爲我有個e tableId,但這似乎過於愚蠢,因爲這兩個組件在字面上呈現在相同的路線。
  • 我也可以在MenuBar上做一個假div,並在我顯示錶格時使用jQuery替換它,但這似乎很不反應。
  • 我也可以爲我的DisplayTable部分應用創建另一個菜單,但我試圖避免混亂。

(我不使用反應路由器4.0如果與自己相關的答案,使用3.0.5,流星的最新版本,但我想這是不是與此有關)

編輯:我想我會在路徑上添加容器,以便我已經有了數據。儘管我會在這裏留下這個以防某人有更好的建議,但這種分類很有意義。

回答

1

雖然有可能是一個更好的方式來做到這一點,我會在下面是我落得這樣解釋:

路線。JSX

Meteor.startup(() => { 
    render(
    <Router history={browserHistory}> 
     <Route path='/' component={App}> 
     //... like before 

     <Route path='/DisplayTable' component={ Comp } > 
      <Route path='/DisplayTable/:tableId' 
      components={{ main: DisplayTable, sidebar: MenuBar }} /> 
     </Route> 

     </Route> 
     <Route path='*' component={NotFound} /> 
    </Router>, 
    document.getElementById('react-root')); 
}); 

然後我添加的組件佈局Comp

Comp.jsx

class Comp extends Component { 
    render() { 
    // this is the final html for our table 
    let displayTable = []; 
    let menuBar = []; 
    // while the data is loading, the html is a spinner 
    if (this.props.loading) { 
     displayTable.push(
     <div key='table-container' className='table-container table-container-no-data'> 
      <div key='loading'> 
      <span>Loading data...</span> 
      <Spinner key='spinner' spinnerName='three-bounce' /> 
      </div> 
     </div>); 
    } else { 
     // the Display Table properties 
     displayTable = React.Children.map(this.props.main, child => React.cloneElement(child, { 
     rows: this.props.rows, 
     cols: this.props.cols, 
     })); 
     // the Menu Bar properties 
     menuBar = React.Children.map(this.props.sidebar, child => React.cloneElement(child, { 
     rows: this.props.rows, 
     cols: this.props.cols, 
     })); 
    } 

    return (
     <div className='container'> 
     <div className="content"> 
      {displayTable} 
     </div> 
     <div className="menu"> 
      {menuBar} 
     </div> 
     </div>); 
    } 
} 

Comp.propTypes = { 
    loading: PropTypes.bool.isRequired, 
    rows: PropTypes.array.isRequired, 
    cols: PropTypes.array.isRequired, 
    //... etc 
}; 
/** 
* A Meteor createContainer component which retrieves data from Meteor & Mongo 
*/ 
export default createContainer((props) => { 
    // get the rows & cols by Meteor subscriptions here, as well as a loading to figure out when the subscription finished (this was originally in DisplayTable) 
} 

DisplayTable.jsx

DisplayTable.propTypes = { 
    rows: PropTypes.array, 
    cols: PropTypes.array, 
}; 

(原來這些都是我需要的,而不是上面 - 使用它們整個組件但從Comp讓他們基本)調用時

MenuBar.jsx

MenuBar.propTypes = { 
    rows: PropTypes.array, 
    cols: PropTypes.array, 
}; 

(同上,用它們的InsertRow)

菜單欄還呼籲InsertRow像這樣:<li><InsertRow tableId={this.props.params.tableId} cols={this.props.cols} isDisabled={false} /></li>