React JSX:在选定的<select>选项上选择“ selected”


402

<select>菜单的React组件中,我需要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>

有解决此问题的推荐方法吗?


仅针对标题提出问题
ericgio

Answers:


647

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>

有关更多信息,请参见React select标签doc


56
使用当前版本的React(0.9),在选项上设置所选属性根本不起作用。而是在选择元素上设置value属性。
liammclennan 2014年

2
我使用ajax.defaultValue加载数据不适用于我。值正在工作,但我无法在选择列表中选择另一个项目。列表正在打开,但是当我选择其中一个时,它会选择值项目。
user1924375

5
@ user1924375,您应该使用onChange事件onChange={this.handleSelect}并为组件设置状态值,例如:'handleSelect:function(){this.setState({value:event.target.value});}`这将使用new重新渲染选择组件选择的项目。希望对您有帮助。
funnydaredevil

1
尽管尚未记录,但如果启用value,a上的prop <select>可以是数组multiselect
tirdadc

4
而是用于defaultValue初始化
dewwwald

70

您可以尝试在尝试设置的“ selected”属性时React警告您的事情<option>

使用 defaultValuevalue道具的<select>设置,而不是selected<option>

因此,您可以options.valuedefaultValue选择的


9
如果我仍要指出当前选中的选项,我该怎么做?我目前唯一能够真正保持选择状态(并保持表单状态以备将来POST)的唯一方法是设置select = true。我尝试设置select元素的defaultValue和value属性,但是通过在选项菜单中将正确的选项设置为selected,这不会在视图中呈现。有什么建议吗?
染色管

4
例子吧?
shinzou

1
不适合我:<select className =“ form-control” value =“ Mois”>
Kuartz,

2
defaultValue不适用于最新版本
Hos Mercury

18

这是一个完整的解决方案,其中结合了最佳答案和其下的评论(这可能会帮助某人努力将其拼凑在一起):

ES6的更新(2019)-使用箭头功能和对象分解

在主要组成部分:

class ReactMain extends React.Component {

  constructor(props) {
    super(props);
    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} handleChange={this.handleChange} />
    )
  }

}

包含的组件(现在是无状态功能):

export const ReactExample = ({ name, value, handleChange }) => (
  <select name={name} value={value} onChange={handleChange}>
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
  </select>
)

上一个答案(使用绑定):

在主要组成部分:

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} handleChange={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>
)

主要组件保持选定的水果值(处于状态),包含的组件显示select元素,并将更新传递回主要组件以更新其状态(然后循环回到包含的组件以更改选定的值)。

请注意,使用名称道具可以使您为同一表单上的其他字段声明单个handleChange方法,而不管它们的类型如何。


请注意,构造函数中的行this.handleChange.bind(this);应为this.handleChange = this.handleChange.bind(this);
Will Shaver's

对于像我这样的人,问他们自己...的含义是什么:reactjs.org/docs/jsx-in-depth.html#spread-attributes
talsibony

@talsibony-确实是传播运算符,但是在我的示例代码中,它只是意味着在此处插入其他代码
安迪·洛伦兹

@AndyLorenz因此,在这种情况下,我建议将其删除... :),或像其他代码一样写注释
talsibony

8

这是如何执行此操作的最新示例。从react docs加上自动绑定的“ fat-arrow”方法语法。

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>
    );
  }
} 


1
***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>);
        }
    });

1
即使没有给出任何解释,也并不需要。解决同一问题的多种方法确实很有帮助。谢谢
DJ2

0

我遇到了问题,即状态更改时,<select>标记无法更新为正确的标记<option>。我的问题似乎是,如果您连续两次渲染两次,第一次是没有预选,<option>而第二次是一次,则<select>标记不会在第二个渲染上更新,而是保留在默认的第一个上。

我使用refs找到了解决方案。您需要获取对<select>标记节点(可能嵌套在某些组件中)的引用,然后在其中手动更新其value上的属性。componentDidUpdate挂钩中。

componentDidUpdate(){
  let selectNode = React.findDOMNode(this.refs.selectingComponent.refs.selectTag);
  selectNode.value = this.state.someValue;
}

0

为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>
  )
}

0

我有一个简单的解决方案是遵循HTML基础。

<input
  type="select"
  defaultValue=""
  >
  <option value="" disabled className="text-hide">Please select</option>
  <option>value1</option>
  <option>value1</option>
</input>

.text-hide 是引导程序的类,如果不使用引导程序,则为:

.text-hide {
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}

-1

我通过设置defaultProps解决了类似的问题:

ComponentName.defaultProps = {
  propName: ''
}

<select value="this.props.propName" ...

因此,如果我的prop在挂载之前不存在,那么我现在可以避免编译错误。


那真的不能解决问题。您将得到以下信息:警告:道具类型失败:您在value没有onChange处理程序的情况下向表单字段提供了道具。这将呈现一个只读字段。如果该字段应可变使用defaultValue。否则,设置onChangereadOnly
詹森·赖斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.