2015-06-01 45 views
1

我與基於JSON數據前檢查單選按鈕解決方案來的,但我覺得代碼可以得到改善。或者應該有更好的實施方法。數據結構如下:如何使檢查單選按鈕陣營

{ 
     radioA: 'Radio A', 
     radioB: 'Radio B', 
     radioC: 'Radio C', 
     selected: 'Radio A' 
    } 

不確定這是否是最好的方法。數據結構可以根據需要進行修改。基於所提供我渲染單選按鈕與它們中的一個的數據

預先選中。以下是我的。

var App = React.createClass({ 

getInitialState: function(){ 
    return { 
     radioA: 'Radio A', 
     radioB: 'Radio B', 
     radioC: 'Radio C', 
     selected: 'Radio A' 
    } 
}, 

render: function(){ 
    return(
     <div>     
      {Object.keys(this.state).map(function(key) { 
       // Not displaying the selected data 
       if(key !== 'selected'){ 

        // Checked radio button 
        if(this.state[key] == this.state['selected']){ 
         return(
          <div> 
           <label className="radio-inline" key={key} htmlFor={key}> 
            <input id={key} type="radio" checked value={key} /> {this.state[key]} 
           </label> 
          </div> 
         ); 
        } 

        else{ 
         return(
          <div> 
           <label className="radio-inline" key={key} htmlFor={key}> 
            <input id={key} type="radio" value={key} /> {this.state[key]} 
           </label> 
          </div> 
         ); 
        } 
       } 
      }, this)} 
     </div> 
    ); 
} 
}); 

React.render(<App />, document.getElementById('container')); 

代碼設置以下jsfiddle.com https://jsfiddle.net/rexonms/2x7ey2L5/

是否有更好的解決方案來實現這一點?在此先感謝

回答

5

確實是有一個更好的辦法。在你render方法,您if語句的兩個分支內的JSX是相同的,不同的是一個具有checked和其他沒有。像這樣的重複可以 - 而且應該 - 幾乎總是被清除。

說明:本答案是以React 0.14爲基礎編寫的。要查看用更現代的React成語編寫的代碼,請參閱this revision

在像JSX checked布爾屬性的情況下,你可以給他們一個truthy或falsy值來控制渲染HTML元素是否具有屬性或沒有。換句話說,如果你有<input checked={10 > 1}/>,你會得到<input checked/>。如果你有<input checked={10 > 100}/>,你會得到<input/>

考慮到這一點,我們就可以降低代碼的東西是這樣的:

var App = React.createClass({ 
 
    getInitialState: function() { 
 
    return { 
 
     radios: { 
 
     radioA: 'Radio A', 
 
     radioB: 'Radio B', 
 
     radioC: 'Radio C' 
 
     }, 
 
     selected: 'radioA' 
 
    } 
 
    }, 
 

 
    renderRadioWithLabel: function(key) { 
 
    var isChecked = key === this.state.selected; 
 

 
    return (
 
     <label className="radio-inline" key={key} htmlFor={key}> 
 
     <input id={key} type="radio" checked={isChecked} value={key} /> 
 
     {this.state.radios[key]} 
 
     </label> 
 
    ); 
 
    }, 
 
    
 
    render: function() { 
 
    return (
 
     <div> 
 
     {Object.keys(this.state.radios).map(function(key) { 
 
      return this.renderRadioWithLabel(key); 
 
     }, this)} 
 
     </div> 
 
    ); 
 
    } 
 
}); 
 
    
 
React.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script> 
 
<div id="container"></div>

正如你所看到的,我已經打破呈現單選按鈕和他們的邏輯標籤變成它自己的功能。你不必這樣做,但我發現它使內循環的函數更容易閱讀,並使你的意圖更清晰。

有些人,包括我自己,會主張打破了邏輯伸到自己的組件,因此您可以有一個狀態容器組件和無狀態的子組件,這使得整個事情很多,更容易測試。 Here's a good article on the topic.您可能想要做的另一件事是讓數組中的鍵和標籤列表,因爲在JavaScript中不保證對象屬性的順序。如果你想知道它會是什麼樣子這些變化,看看這個片斷:

var Radio = React.createClass({ 
 
    render: function() { 
 
    var key = this.props.key; 
 
    return (
 
     <label className="radio-inline" key={key} htmlFor={key}> 
 
     <input id={key} type="radio" checked={this.props.selected} value={key} /> 
 
     {this.props.label} 
 
     </label> 
 
    ); 
 
    } 
 
}); 
 

 
var RadiosContainer = React.createClass({ 
 
    getInitialState: function() { 
 
    return { selected: this.props.initialSelected }; 
 
    }, 
 
    
 
    render: function() { 
 
    return (
 
     <div> 
 
     {this.props.radios.map(function(radioProps) { 
 
      var selected = this.state.selected === radioProps.key; 
 
      return <Radio {...radioProps} selected={selected} />; 
 
     }, this)} 
 
     </div> 
 
    ); 
 
    } 
 
}); 
 

 
var radios = [ 
 
    { key: 'radioA', label: 'Radio A' }, 
 
    { key: 'radioB', label: 'Radio B' }, 
 
    { key: 'radioC', label: 'Radio C' } 
 
]; 
 
var selectedRadio = 'radioB'; 
 

 
React.render(
 
    <RadiosContainer radios={radios} initialSelected={selectedRadio} />, 
 
    document.getElementById('container') 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script> 
 
<div id="container"></div>

+0

不幸在你的jsfiddle例如不工作 - 你不能改變的單選按鈕。 –

+0

小提琴按預期工作。在陣營文檔要理解爲什麼你不能改變的單選按鈕,這是無關的OP的問題,瞭解受控和非受控組件:https://facebook.github.io/react/docs/forms.html –