React JSX: выбор "selected" для выбранного варианта <select>
В компоненте React для меню <select>
мне нужно установить атрибут selected
в опции, которая отражает состояние приложения.
В render()
, optionState
передается от владельца состояния к компоненту SortMenu. Значения опций передаются как props
из JSON.
render: function() {
var options = [],
optionState = this.props.optionState;
this.props.options.forEach(function(option) {
var selected = (optionState === option.value) ? ' selected' : '';
options.push(
<option value={option.value}{selected}>{option.label}</option>
);
});
// pass {options} to the select menu jsx
Однако это вызывает синтаксическую ошибку при компиляции JSX.
Это избавляет от синтаксической ошибки, но, очевидно, не решает проблему:
var selected = (optionState === option.value) ? 'selected' : 'false';
<option value={option.value} selected={selected}>{option.label}</option>
Я также пробовал это:
var selected = (optionState === option.value) ? true : false;
<option value={option.value} {selected ? 'selected' : ''}>{option.label}</option>
Есть ли рекомендуемый способ решения этого вопроса?
Ответы
Ответ 1
React автоматически понимает логические значения для этой цели, поэтому вы можете просто написать (обратите внимание: не рекомендуется)
<option value={option.value} selected={optionsState == option.value}>{option.label}</option>
и он будет выводить "выбранный" соответствующим образом.
Тем не менее, React делает это еще проще для вас. Вместо определения selected
для каждого параметра вы можете (и должны) просто написать value={optionsState}
в самом теге select:
<select value={optionsState}>
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
Дополнительные сведения см. В документе dact.
Ответ 2
Вы можете сделать то, что React предупреждает вас, когда вы пытаетесь установить "выбранное" свойство <option>
:
Используйте реквизиты defaultValue
или value
на <select>
вместо настройки selected
на <option>
.
Итак, вы можете использовать options.value
в defaultValue
выбранного вами
Ответ 3
Вот полное решение, которое включает в себя лучший ответ и комментарии под ним (что может помочь кому-то изо всех сил пытаться собрать все это вместе):
в основном компоненте:
class ReactMain extends React.Component {
constructor(props) {
super(props);
// bind once here, better than multiple times in render
this.handleChange = this.handleChange.bind(this);
this.state = { fruit: props.item.fruit };
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
saveItem() {
const item = {};
item.fruit = this.state.fruit;
// do more with item object as required (e.g. save to database)
}
render() {
return (
<ReactExample name="fruit" value={this.state.fruit} onChange{this.handleChange} />
)
}
}
(который теперь является функционалом без гражданства):
export const ReactExample = (props) => (
<select name={props.name} value={props.value} onChange={props.handleChange}>
<option value="A">Apple</option>
<option value="B">Banana</option>
<option value="C">Cranberry</option>
</select>
)
основной компонент поддерживает выбранное значение для фруктов (в состоянии), включенный компонент отображает элемент выбора, а обновления передаются обратно основному компоненту для обновления его состояния (которое затем возвращается к включенному компоненту для изменения выбранного значения).
Обратите внимание на использование имени prop, которое позволяет объявить один метод handleChange для других полей в одной и той же форме независимо от их типа.
Ответ 4
***Html:***
<div id="divContainer"></div>
var colors = [{ Name: 'Red' }, { Name: 'Green' }, { Name: 'Blue' }];
var selectedColor = 'Green';
ReactDOM.render(<Container></Container>, document.getElementById("divContainer"));
var Container = React.createClass({
render: function () {
return (
<div>
<DropDown data={colors} Selected={selectedColor}></DropDown>
</div>);
}
});
***Option 1:***
var DropDown = React.createClass(
{
render: function () {
var items = this.props.data;
return (
<select value={this.props.Selected}>
{
items.map(function (item) {
return <option value={item.Name }>{item.Name}</option>;
})
}
</select>);
}
});
***Option 2:***
var DropDown = React.createClass(
{
render: function () {
var items = this.props.data;
return (
<select>
{
items.map(function (item) {
return <option value={item.Name} selected={selectedItem == item.Name}>{item.Name}</option>;
})
}
</select>);
}
});
***Option 3:***
var DropDown = React.createClass(
{
render: function () {
var items = this.props.data;
return (
<select>
{
items.map(function (item) {
if (selectedItem == item.Name)
return <option value={item.Name } selected>{item.Name}</option>;
else
return <option value={item.Name }>{item.Name}</option>;
})
}
</select>);
}
});
Ответ 5
Просто добавьте как первый вариант вашего тега select:
<option disabled hidden value=''></option>
Это станет дефолтом, и когда вы выберете допустимый вариант, будет установлен в вашем состоянии
Ответ 6
У меня была проблема с тегами <select>
, не обновляющимися до правильного <option>
при изменении состояния. Моя проблема заключалась в том, что если вы выполняете дважды в быстрой последовательности, первый раз без предварительно выбранного <option>
, а во второй раз с одним, то тег <select>
не обновляется во втором рендере, но остается на сначала по умолчанию.
Я нашел решение для этого, используя refs. Вам нужно получить ссылку на тэг <select>
node (который может быть вложен в некоторый компонент), а затем вручную обновить свойство value
на нем, в componentDidUpdate
.
componentDidUpdate(){
let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag);
selectNode.value = this.state.someValue;
}
Ответ 7
Проводка аналогичного ответа для MULTISELECT/optgroups:
render() {
return(
<div>
<select defaultValue="1" onChange={(e) => this.props.changeHandler(e.target.value) }>
<option disabled="disabled" value="1" hidden="hidden">-- Select --</option>
<optgroup label="Group 1">
{options1}
</optgroup>
<optgroup label="Group 2">
{options2}
</optgroup>
</select>
</div>
)
}
Ответ 8
Вот последний пример того, как это сделать. Из интерактивных документов, а также автоматическое связывание синтаксиса метода "жирная стрелка".
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
}
handleChange = (event) =>
this.setState({value: event.target.value});
handleSubmit = (event) => {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Ответ 9
У меня есть простое решение, следуя основному HTML.
<input
type="select"
defaultValue=""
>
<option value="" disabled className="text-hide">Please select</option>
<option>value1</option>
<option>value1</option>
</input>
.text-hide
- это класс начальной загрузки, если вы не используете bootstrap, вот вы:
.text-hide {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
Ответ 10
Я столкнулся с подобной проблемой, установив defaultProps:
ComponentName.defaultProps = {
propName: ''
}
<select value="this.props.propName"...
Поэтому теперь я избегаю ошибок при компиляции, если моя опора не существует до ее установки.