2016-10-10 53 views
0

比方說,我有一個富組件與一些陣營路由器導航:與擴展成分發生化學反應路由器

var Foo = React.createClass({ 
    render: function() { 
     return (<div> 
      <Link to="/foo/1">1</Link>; 
      <Link to="/foo/2">2</Link>; 
      {this.props.children} 
     </div>); 
    } 
}); 
var Foo1 = React.createClass({ 
    render: function() { 
     return <p>foo 1</p>; 
    } 
}); 
var Foo2 = React.createClass({ 
    render: function() { 
     return <p>foo 2</p>; 
    } 
}); 
ReactDOM.render((
    <Router> 
     <Route path="/" ...> 
      <Route path="foo" component={Foo}> 
       <Route path="1" component={Foo1} /> 
       <Route path="2" component={Foo2} /> 
      </Route> 
     </Route> 
    </Router> 
), document.getElementById('main')); 

現在,讓我們說,我也有一個酒吧組成部分,這是非常相似的(除了,還有,bar代替foo)。在「經典」陣營的應用,我會「提取」普通邏輯的,就像這樣:

var Element = React.createClass({ 
    render: function() { 
     return (<div> 
      <Link to={this.props.url + '/1'}>1</Link>; 
      <Link to={this.props.url + '/2'}>2</Link>; 
      {this.props.children && React.cloneElement(this.props.children { 
       name: this.props.name // Ugly hack to propagate props... 
      })} 
     </div>); 
    } 
}); 
var Element1 = React.createClass({ 
    render: function() { 
     return <p>{this.props.name} 1</p>; 
    } 
}); 
var Element2 = React.createClass({ 
    render: function() { 
     return <p>{this.props.name} 2</p>; 
    } 
}); 
var Foo = React.createClass({ 
    render: function() { 
     return <Element url="/foo" name="foo" />; 
    } 
}); 
var Bar = React.createClass({ 
    render: function() { 
     return <Element url="/bar" name="bar" />; 
    } 
}); 

正如你所看到的,我已經幾乎得到它(甚至是醜陋的道具傳播的黑客行爲。 ..)。我缺少的部分是如何定義的路由本身:

ReactDOM.render((
    <Router> 
     <Route path="/" ...> 
      <Route path="foo" component={Foo}> 
       <Route path="1" component={?} /> 
       <Route path="2" component={?} /> 
      </Route> 
     </Route> 
    </Router> 
), document.getElementById('main')); 

我的意思是,不再有Foo1Foo2成分,因爲富有Element,從它們一般的。當然,我可以明確地定義Foo1以使Element1Foo2具有Element2,但是然後我必須實施Foo而不是讓Element爲我做;或者也許我可以通過組件本身的道具(即Foo = ... <Element ... component1={Foo1} component2={Foo2} /> ...但是然後呢?)。

所以:我如何能達到這種陣營,白條「通過組成繼承」與之反應路由器上的?或者有另一種方法可以做到這一點?

回答

0

我想到了一個解決方案,所以我想我會發布它爲人們提供了類似的問題。請注意我對這個還是新的..呃..「心態」,所以它可能不是最好的方式。

這裏的東西:該富/酒吧差(url="/foo|/bar"name="foo|bar")可以被「總結」成單個"foo|bar"標籤,然後可將其提取到的URL作爲參數。那就是:

ReactDOM.render((
    <Router> 
     <Route path="/" ...> 
      <Route path="/:tag" component={Element}> 
       <Route path="/:tag/1" component={Element1} /> 
       <Route path="/:tag/2" component={Element2} /> 
      </Route> 
     </Route> 
    </Router> 
), document.getElementById('main')); 

而且元素可以被改寫,以這個標籤到:

var Element = React.createClass({ 
    render: function() { 
     return (<div> 
      <Link to={'/' + this.props.params.tag + '/1'}>1</Link>; 
      <Link to={'/' + this.props.params.tag + '/2'}>2</Link>; 
      {this.props.children} 
     </div>); 
    } 
}); 
var Element1 = React.createClass({ 
    render: function() { 
     return <p>{this.props.params.tag} 1</p>; 
    } 
}); 
var Element2 = React.createClass({ 
    render: function() { 
     return <p>{this.props.params.tag} 2</p>; 
    } 
}); 

就是這樣!你甚至都不需要<Foo /><Bar />組件。

的原因,我不能完全贊同這一解決方案是,它適用於一個很簡單的情況下(如本例中,或實際CMS我的工作),但我不知道它擴展到更復雜的設計;這一點,還有的URL衝突:用<Baz />組件必須先出現一個/baz路線,否則與"baz"標籤的<Element />將代替評估。我還沒有找到如何用React Router定義複雜參數(如正則表達式),但如果我這樣做,我會更新答案。