React JSX: выбор "selected" на выбранном параметре
в компоненте 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>
есть ли рекомендуемый способ решения этой?
10 ответов:
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>подробнее на http://facebook.github.io/react/docs/forms.html#why-select-value.
вы можете сделать то, что React предупреждает вас, когда вы пытаетесь установить" выбранное " свойство
<option>:использовать
defaultValueилиvalueреквизит на<select>вместоselectedon<option>.Итак, вы можете использовать
options.valueнаdefaultValueтвой выбор
вот полное решение, которое включает в себя лучший ответ и комментарии ниже него (что может помочь кому-то изо всех сил, чтобы собрать все это вместе):
В главных компонента:
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 для других полей в той же форме независимо от их типа.
***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>); } });
у меня была проблема с
<select>теги не правильные<option>при изменении состояния. Моя проблема заключалась в том, что если вы рендерите дважды подряд, в первый раз без предварительно выбранного<option>но второй раз с одним, то<select>тег не обновляется на втором рендере, но остается на первом по умолчанию .я нашел решение этой проблемы с помощью refs. Вам нужно получить ссылку на ваш
<select>узел тега (который может быть вложенным в некоторых компонентах), а затем вручную обновитьvalueсвойство на нем, вcomponentDidUpdateкрюк.componentDidUpdate(){ let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag); selectNode.value = this.state.someValue; }
просто добавьте в качестве первого варианта вашего тега select:
<option disabled hidden value=''></option>это станет по умолчанию, и когда вы выберете действительный параметр будет установлен на вашем состоянии
публикация аналогичного ответа для 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> ) }
вот последний пример того , как это сделать, от react docs
class FlavorForm extends React.Component { constructor(props) { super(props); this.state = {value: 'coconut'}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } 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 La Croix 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> ); } }
у меня есть простое решение, следующее за базовым HTML.
<input type="select" defaultValue="" > <option value="" disabled className="text-hide">Please select</option> <option>value1</option> <option>value1</option> </input>
.text-hideэто класс bootstrap, если вы не используете bootstrap, вот вы:.text-hide { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; }
Я обошел аналогичную проблему, установив defaultProps:
ComponentName.defaultProps = { propName: '' }
<select value="this.props.propName" ...Так что теперь я избегаю ошибок при компиляции, если моя опора не существует до монтажа.
Comments