如何在 React 中呈现选中的单选按钮
How to render checked radio button in React
我想出了一个基于 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/
有没有更好的解决方案来实现这个?提前致谢
确实有更好的办法。在您的 render
方法中, if
语句的两个分支内的 JSX 是相同的,除了一个有 checked
而另一个没有。像这样的重复可以——而且应该——几乎总是被清理干净。
Note: This answer was written with React 0.14 in mind. To see the code as written with more modern React idioms, see 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>
如您所见,我将呈现单选按钮及其标签的逻辑分解为它自己的函数。您不必这样做,但我发现它使带有内部循环的 render
函数更易于阅读,并使您的意图更清晰。
有些人,包括我自己,会提倡将该逻辑分解成它自己的组件,这样您就可以拥有一个有状态的容器组件和无状态的子组件,这使得整个事情更容易测试。 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>
我想出了一个基于 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/
有没有更好的解决方案来实现这个?提前致谢
确实有更好的办法。在您的 render
方法中, if
语句的两个分支内的 JSX 是相同的,除了一个有 checked
而另一个没有。像这样的重复可以——而且应该——几乎总是被清理干净。
Note: This answer was written with React 0.14 in mind. To see the code as written with more modern React idioms, see 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>
如您所见,我将呈现单选按钮及其标签的逻辑分解为它自己的函数。您不必这样做,但我发现它使带有内部循环的 render
函数更易于阅读,并使您的意图更清晰。
有些人,包括我自己,会提倡将该逻辑分解成它自己的组件,这样您就可以拥有一个有状态的容器组件和无状态的子组件,这使得整个事情更容易测试。 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>