2014-12-06 70 views
2

我想清理我的JSX以將演示標記與功能標記/ DOM元素分開。如何減少我的reactjs/JSX中的標記數量

我有一個表單,它將成爲我的組件層次結構的頂層。在下面會有幾個輸入和表單元素組成整個組件層次結構。還會有相當數量的twitter引導「cruft」,主要是爲了控制演示文稿。

例如:

render: function() { 
    return (
    <form role="form" className="form-horizontal"> 
     <div className="form-group"> 
     <label htmlFor="homePrice">Home Price</label> 
     <div className="input-group input-group-lg"> 
      <span className="input-group-addon">$</span> 
      <input id="homePrice" 
      className="form-control" 
      onChange={this.priceChange} 
      value={this.state.homePrice} 
      /> 
     </div> 
     </div> 
     <div className="form-group"> 
     <label htmlFor="depositAmount">Deposit Amount</label> 
     <div className="input-group input-group-lg"> 
      <span className="input-group-addon">$</span> 
      <input id="depositAmount" 
      className="form-control" 
      onChange={this.depositChange} 
      value={this.state.depositAmount} 
      /> 
     </div> 
     </div> 
     ... snip ... 

理想我有<form>單獨的組件,併爲每個<inputs>的那麼個別子組件,在沒有標籤標記或<div className="form-group"><span className="input-group-addon">,並且能夠插入這些成各種指向HTML文檔並維護組件層次結構。

那麼,我該如何做到這一點,並維護組件層次結構。更改輸入中的值會影響父級最頂層組件中的狀態。

謝謝。

回答

6

你可以通過合成相當有效地做到這一點。您希望自定義組件如何定製就取決於您;使用更多的道具和條件邏輯,您可以獲得更多的可定製性。

我會經常寫標記開始/ JSX我希望我可以使用:

render: function() { 
    return (
    <Form horizontal> 
     <Input id="homePrice" 
      addon="$" label="Home Price" 
      onChange={this.priceChange} 
      value={this.state.homePrice} /> 
     <Input id="depositAmount" 
      addon="$" label="Deposit Amount" 
      onChange={this.depositChange} 
      value={this.state.depositAmount} /> 
    </Form> 
); 
} 

然後就可以開始實施的組件需要,使其工作:

var Form = React.createClass({ 
    render: function() { 
    var direction = "vertical"; 
    if (this.props.horizontal) direction="horizontal"; 

    return (
     <form role="form" className={"form-" + direction} 
      onSubmit={this.props.onSubmit}> 
     {this.props.children} 
     </form> 
    ); 
    } 
}); 

var Input = React.createClass({ 
    render: function() { 
    return (
     <div className="form-group"> 
     <label htmlFor={this.props.id}>{this.props.label}</label> 
     <div className="input-group input-group-lg"> 
      <span className="input-group-addon">{this.props.addon}</span> 
      <input id={this.props.id} 
       className="form-control" 
       onChange={this.props.onChange} 
       value={this.props.value} /> 
     </div> 
     </div> 
    ); 
    } 
}); 

通過利用this.props.children,getDefaultProps,展開運算符(例如通過<someElement {...this.props} />將道具轉移到新元素)和條件,您可以爲更復雜的組件創建非常好的抽象秒。此外,propTypes允許您指定組件所需的屬性,用作文檔以及捕獲開發中的運行時錯誤的方法。

您可以考慮檢查React Bootstrap的源代碼以瞭解它們如何實現複合組件以包裝更復雜的Bootstrap HTML;例如,這裏是你會寫使用卡組件是什麼:如果您更感興趣的描述結構的表單,然後讓庫自動創建的元素

<TabbedArea defaultActiveKey={2}> 
    <TabPane eventKey={1} tab="Tab 1">TabPane 1 content</TabPane> 
    <TabPane eventKey={2} tab="Tab 2">TabPane 2 content</TabPane> 
</TabbedArea> 

,你可以看看像React Forms這樣的項目:

function Person(props) { 
    props = props || {} 
    return (
    <Schema name={props.name} label={props.label}> 
     <Property name="first" label="First name" /> 
     <Property name="last" label="Last name" /> 
    </Schema> 
) 
} 

var family = (
    <Schema> 
    <Person name="mother" label="Mother" /> 
    <Person name="father" label="Father" /> 
    <List name="children" label="Children"> 
     <Person /> 
    </List> 
    </Schema> 
) 

React.renderComponent(
    <Form schema={family} />, 
    document.getElementById('example'))