在<select>菜单的React组件中,我需要在反映应用程序状态的选项上设置所选属性。

在render()中,optionState从状态所有者传递给SortMenu组件。选项值作为道具从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>

有没有解决这个问题的推荐方法?


当前回答

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

ComponentName.defaultProps = {
  propName: ''
}

<选择value = " this.props。propName”…

所以现在,如果我的道具在安装之前不存在,我可以避免在编译时出错。

其他回答

如果你使用无状态,那么

const IndexPage =({states, selectedState}) => {
return(
    <select id="states" defaultValue={selectedState} name="state">
{states.map(state=> (
                      <option value={state.id} key={state.id}>{state.name}</option>
                      ))
                      }
                    </select>
)
}

简单地添加作为选择标签的第一个选项:

<option disabled hidden value=''></option>

这将成为默认值,当您选择一个有效的选项将设置在您的状态

下面是一个完整的解决方案,包含了最佳答案和下面的评论(这可能会帮助那些挣扎着把它们拼凑在一起的人):

UPDATE FOR 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>
)

主组件维护fruit的选中值(处于状态),被包含的组件显示select元素并将更新传递回主组件以更新其状态(然后循环回被包含的组件以更改所选值)。

请注意,使用了名称道具,它允许您为同一表单上的其他字段声明一个handleChange方法,而不管它们的类型是什么。

针对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文档,加上自动绑定“肥箭头”方法语法。

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