2016-10-10 16 views
0

Скажем, у меня есть компонент Foo с некоторыми Реагировать маршрутизатора навигации:Продление компоненты с React Router

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, который очень похож (за исключением, ну bar вместо foo). В «классическом» React приложения, я бы «извлеченный» общая логику из, например, так:

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')); 

Я имею в виду, больше не Foo1 и Foo2 компоненты, потому что Foo имеет Element, из которого они генетически производных. Я мог бы, конечно, явно определить Foo1, чтобы иметь Element1 и Foo2, чтобы иметь Element2, но тогда мне пришлось бы реализовать Foo вместо того, чтобы позволить Element сделать это за меня; или, может быть, я мог бы передать сами компоненты в качестве реквизита (т. е. Foo = ... <Element ... component1={Foo1} component2={Foo2} /> ... но тогда что?).

Итак: как я могу достичь такого рода реактивного «наследования через композицию» с помощью React Router? Или есть другой способ сделать это?

ответ

0

Я думал о решении, поэтому подумал, что отправлю его для людей с аналогичной проблемой. Обратите внимание, что я все еще новичок в этом .. ух .. «mindset», так что это может быть не самый лучший способ.

Вот вещь: разница Foo/бар (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 />, иначе вместо него будет оцениваться <Element /> с тегом "baz". Я все еще не нашел, как определить сложные параметры (например, регулярные выражения) с React Router, но если да, то я обновлю ответ.

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