在<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>

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


当前回答

使用React 16.8。我们可以像下面的例子一样使用钩子来实现这一点

Codesandbox链接

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const options = [
    "Monty Python and the Holy Grail",
    "Monty Python's Life of Brian",
    "Monty Python's The Meaning of Life"
  ];
  const filmsByTati = [
    {
      id: 1,
      title: "Jour de fête",
      releasedYear: 1949
    },
    {
      id: 2,
      title: "Play time",
      releasedYear: 1967
    },
    {
      id: 3,
      releasedYear: 1958,
      title: "Mon Oncle"
    }
  ];
  const [selectedOption, setSelectedOption] = useState(options[0]);
  const [selectedTatiFilm, setSelectedTatiFilm] = useState(filmsByTati[0]);
  return (
    <div className="App">
      <h1>Select Example</h1>
      <select
        value={selectedOption}
        onChange={(e) => setSelectedOption(e.target.value)}
      >
        {options.map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
      <span>Selected option: {selectedOption}</span>

      <select
        value={selectedTatiFilm}
        onChange={(e) =>
          setSelectedTatiFilm(
            filmsByTati.find(film => (film.id == e.target.value))
          )
        }
      >
        {filmsByTati.map((film) => (
          <option key={film.id} value={film.id}>
            {film.title}
          </option>
        ))}
      </select>
      <span>Selected option: {selectedTatiFilm.title}</span>
    </div>
  );
}

其他回答

当你试图设置<option>的"selected"属性时,你可以做React警告你的事情:

在<select>上使用defaultValue或value道具,而不是在<option>上使用设置。

所以,你可以使用选项。在您选择的defaultValue上

如果你使用无状态,那么

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

下面是如何做到这一点的最新例子。来自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>
    );
  }
} 

使用React 16.8。我们可以像下面的例子一样使用钩子来实现这一点

Codesandbox链接

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const options = [
    "Monty Python and the Holy Grail",
    "Monty Python's Life of Brian",
    "Monty Python's The Meaning of Life"
  ];
  const filmsByTati = [
    {
      id: 1,
      title: "Jour de fête",
      releasedYear: 1949
    },
    {
      id: 2,
      title: "Play time",
      releasedYear: 1967
    },
    {
      id: 3,
      releasedYear: 1958,
      title: "Mon Oncle"
    }
  ];
  const [selectedOption, setSelectedOption] = useState(options[0]);
  const [selectedTatiFilm, setSelectedTatiFilm] = useState(filmsByTati[0]);
  return (
    <div className="App">
      <h1>Select Example</h1>
      <select
        value={selectedOption}
        onChange={(e) => setSelectedOption(e.target.value)}
      >
        {options.map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
      <span>Selected option: {selectedOption}</span>

      <select
        value={selectedTatiFilm}
        onChange={(e) =>
          setSelectedTatiFilm(
            filmsByTati.find(film => (film.id == e.target.value))
          )
        }
      >
        {filmsByTati.map((film) => (
          <option key={film.id} value={film.id}>
            {film.title}
          </option>
        ))}
      </select>
      <span>Selected option: {selectedTatiFilm.title}</span>
    </div>
  );
}

React让你更容易做到这一点。而不是在每个选项上定义selected,你可以(也应该)简单地在select标签上写value={optionsState}:

<select value={optionsState}>
  <option value="A">Apple</option>
  <option value="B">Banana</option>
  <option value="C">Cranberry</option>
</select>

有关更多信息,请参阅React选择标签文档。

此外,React会自动理解布尔值,所以你可以简单地写(注意:不推荐)

<option value={option.value} selected={optionsState == option.value}>{option.label}</option>

它会适当地输出" selected "