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

IT技术 javascript reactjs
2021-01-24 04:45:45

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

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

6个回答

React 让这对你来说更容易。您可以(并且应该)简单地写在 select 标签本身上selected而不是在每个选项上定义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>

它将适当地输出“选定”。

而是用于defaultValue初始化
2021-03-20 04:45:45
尝试在 <select> 上使用 defaultValue,但请注意:当 <select> 呈现时,<options> 必须已经可用,否则将无法工作。如果您在渲染 <select> 后异步加载选项,那么您可能必须在 <option> 上使用 selected={condition} 才能使其工作。或者,渲染一些其他控件,例如 Spinner,直到所有值都可用。
2021-03-22 04:45:45
@user1924375 您应该使用 onChange 事件onChange={this.handleSelect}并为您的组件设置状态值,例如: 'handleSelect: function() { this.setState({value: event.target.value});}` 这将使用 new 重新渲染您的选择组件所选项目。希望它会帮助你。
2021-03-28 04:45:45
使用当前版本的 React (0.9) 设置选项的 selected 属性根本不起作用。改为在 select 元素上设置 value 属性。
2021-04-04 04:45:45
我用 ajax.defaultValue 加载数据对我不起作用。值正在工作,但我无法在选择列表中选择另一个项目。列表正在打开,但是当我选择其中一个时,它选择了值项目。知道吗?
2021-04-04 04:45:45

当您尝试设置 的“selected”属性时,您可以执行 React 警告您的操作<option>

使用defaultValuevalueprops on<select>而不是设置selectedon <option>

所以,你可以options.valuedefaultValue你的选择上使用

如果我仍然想指示当前选择的选项,我该怎么做?我目前能够实际保持选中该选项(并保持表单状态以供将来发布)的唯一方法是设置 select=true。我曾尝试设置 select 元素的 defaultValue 和 value 属性,但这不会通过在选项菜单中将正确的选项设置为 selected 来呈现在视图中。有什么建议吗?
2021-03-29 04:45:45
我既不@Kuartz
2021-03-31 04:45:45
不适合我:<select className="form-control" value="Mois">
2021-04-12 04:45:45
例子也许??
2021-04-13 04:45:45

这是一个完整的解决方案,其中包含最佳答案及其下方的评论(这可能有助于努力拼凑的人):

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

主组件维护水果的选定值(处于状态),包含的组件显示选择元素,更新被传递回主组件以更新其状态(然后循环回到包含的组件以更改选定的值)。

请注意 name prop 的使用,它允许您为同一表单上的其他字段声明一个 handleChange 方法,而不管它们的类型。

@talsibony - 这确实是扩展运算符,但在我的示例代码中,它只是意味着在此处插入一些其他代码
2021-03-15 04:45:45
注意构造函数中的行this.handleChange.bind(this);应该是this.handleChange = this.handleChange.bind(this);
2021-03-18 04:45:45
@AndyLorenz 所以在这种情况下,我建议将其删除... :),或者只写注释,例如 // 其余代码
2021-03-27 04:45:45
对于像我这样问他们自己......意味着什么的人:reactjs.org/docs/jsx-in-depth.html#spread-attributes
2021-04-08 04:45:45

这是有关如何执行此操作的最新示例。来自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>
    );
  }
} 

使用 React 16.8。我们可以使用钩子来做到这一点,如下例所示

代码沙盒链接

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