【问题标题】:React JSX: selecting "selected" on selected <select> optionReact JSX:在选定的 <select> 选项上选择“选定”
【发布时间】:2014-03-11 03:03:48
【问题描述】:

&lt;select&gt; 菜单的 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>

有没有推荐的解决方法?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    React 让这一切变得更容易。除了在每个选项上定义selected您可以(并且应该)简单地在选择标签本身上写value={optionsState}

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

    有关详细信息,请参阅the React select tag doc

    此外,React 会为此目的自动理解布尔值,因此您可以简单地编写 (注意:不推荐)

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

    它会适当地输出'selected'。

    【讨论】:

    • 在当前版本的 React (0.9) 上设置 selected 属性的选项根本不起作用。而是在 select 元素上设置 value 属性。
    • 我用 ajax.defaultValue 加载数据对我不起作用。值正在工作,但我无法在选择列表中选择另一个项目。列表正在打开,但是当我选择其中一个时,它会选择值项目。知道吗?
    • @user1924375 您应该使用 onChange 事件 onChange={this.handleSelect} 并为您的组件设置状态值,例如:'handleSelect: function() { this.setState({value: event.target.value}) ;}` 这将使用新的选定项重新呈现您的选择组件。希望对你有帮助。
    • 宁可使用defaultValue来初始化
    • 尝试在 被渲染时, 必须已经可用,否则它将不起作用。如果您在渲染
    【解决方案2】:

    当你尝试设置 &lt;option&gt; 的“selected”属性时,你可以做 React 警告你的事情:

    &lt;select&gt; 上使用defaultValuevalue 属性,而不是在&lt;option&gt; 上设置selected

    因此,您可以在您选择的defaultValue 上使用options.value

    【讨论】:

    • 如果我仍然想指出当前选择的选项,我该怎么做呢?我目前能够实际保持选中选项(并保持表单状态以供将来发布)的唯一方法是设置 select=true。我已经尝试设置 select 元素的 defaultValue 和 value 道具,但是通过在选项菜单中设置正确的选项来选择它不会在视图中呈现。有什么建议吗?
    • 也许是例子??
    • 不适合我:
    • 我也不是@Kuartz
    【解决方案3】:

    当状态改变时,&lt;select&gt; 标签没有更新到正确的&lt;option&gt; 时遇到问题。我的问题似乎是,如果你快速连续渲染两次,第一次没有预选&lt;option&gt;,但第二次有一个,那么&lt;select&gt; 标签不会在第二次渲染时更新,而是保持不变默认第一个。

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

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

    【讨论】:

      【解决方案4】:
      ***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>);
              }
          });
      

      【讨论】:

      • 尽管没有给出任何解释,但实际上并不需要。解决同一问题的多种方法确实很有帮助。谢谢
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        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 属性的使用,它允许您为同一表单上的其他字段声明单个 handleChange 方法,而不管它们的类型如何。

        【讨论】:

        • 注意构造函数中this.handleChange.bind(this);的行应该是this.handleChange = this.handleChange.bind(this);
        • 对于像我这样问自己...意味着什么的人:reactjs.org/docs/jsx-in-depth.html#spread-attributes
        • @talsibony - 这确实是扩展运算符,但在我的示例代码中,它只是意味着 在此处插入一些其他代码
        • @AndyLorenz 所以在这种情况下我会建议删除它... :),或者只是写评论 // 其余代码
        【解决方案7】:

        只需添加为您的选择标签的第一个选项:

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

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

        【讨论】:

          【解决方案8】:

          这是如何做到这一点的最新示例。来自react docs,加上自动绑定的“胖箭头”方法语法。

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

          【讨论】:

            【解决方案9】:

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

            ComponentName.defaultProps = {
              propName: ''
            }
            

            &lt;select value="this.props.propName" ...

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

            【讨论】:

            • 这真的不能解决问题。你会得到这个:警告:失败的道具类型:你提供了一个value 道具给一个没有onChange 处理程序的表单字段。这将呈现一个只读字段。如果该字段应该是可变的,请使用defaultValue。否则,设置onChangereadOnly
            【解决方案10】:

            我有一个简单的解决方案是遵循 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;
            }
            

            【讨论】:

              【解决方案11】:

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

              Codesandbox link

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

              【讨论】:

                【解决方案12】:

                使用defaultValue 预选 Select 的值。

                <Select defaultValue={[{ value: category.published, label: 'Publish' }]} options={statusOptions} onChange={handleStatusChange} />
                

                【讨论】:

                  【解决方案13】:

                  我正在为语言选择器制作一个下拉菜单 - 但我需要下拉菜单来在页面加载时显示当前语言。我要么从 URL 参数example.com?user_language=fr 获取我的初始语言,要么从用户的浏览器设置中检测它。然后当用户与下拉菜单交互时,所选语言将被更新,并且语言选择器下拉菜单将显示当前选择的语言。

                  由于整个线程一直在提供水果示例,所以我为您准备了各种水果。

                  • 首先,用一个基本的 React 功能组件回答最初提出的问题 - 两个带有和不带有 props 的示例,然后是如何在其他地方导入组件。

                  • 接下来,同样的例子 - 但使用 Typescript 进行了优化。

                  • 然后是一个额外的结局 - 使用 Typescript 的语言选择器下拉组件。


                  基本 React (16.13.1) 功能组件示例。 FruitSelectDropdown 的两个示例,一个没有道具,一个接受道具 fruitDetector

                  import React, { useState } from 'react'
                  
                  export const FruitSelectDropdown = () => {
                    const [currentFruit, setCurrentFruit] = useState('oranges')
                    
                    const changeFruit = (newFruit) => {
                      setCurrentFruit(newFruit)
                    }
                    
                    return (
                      <form>
                        <select 
                          onChange={(event) => changeFruit(event.target.value)}
                          value={currentFruit}
                        >
                          <option value="apples">Red Apples</option>
                          <option value="oranges">Outrageous Oranges</option>
                          <option value="tomatoes">Technically a Fruit Tomatoes</option>
                          <option value="bananas">Bodacious Bananas</option>
                        </select>
                      </form>
                    )
                  }
                  

                  或者你可以让 FruitSelectDropdown 接受 props,也许你有一个输出字符串的函数,你可以使用 fruitDetector prop 传递它

                  import React, { useState } from 'react'
                  
                  export const FruitSelectDropdown = ({ fruitDetector }) => {
                    const [currentFruit, setCurrentFruit] = useState(fruitDetector)
                    
                    const changeFruit = (newFruit) => {
                      setCurrentFruit(newFruit)
                    }
                    
                    return (
                      <form>
                        <select 
                          onChange={(event) => changeFruit(event.target.value)}
                          value={currentFruit}
                        >
                          <option value="apples">Red Apples</option>
                          <option value="oranges">Outrageous Oranges</option>
                          <option value="tomatoes">Technically a Fruit Tomatoes</option>
                          <option value="bananas">Bodacious Bananas</option>
                        </select>
                      </form>
                    )
                  }
                  

                  然后将FruitSelectDropdown 导入应用中的其他位置

                  import React from 'react'
                  import { FruitSelectDropdown } from '../path/to/FruitSelectDropdown'
                  
                  const App = () => {
                    return (
                      <div className="page-container">
                        <h1 className="header">A webpage about fruit</h1>
                        <div className="section-container">
                          <h2>Pick your favorite fruit</h2>
                          <FruitSelectDropdown fruitDetector='bananas' />
                  
                        </div>
                      </div>
                    )
                  }
                  
                  export default App
                  

                  FruitSelectDropdown 使用打字稿

                  import React, { FC, useState } from 'react'
                  
                  type FruitProps = {
                    fruitDetector: string;
                  }
                  
                  export const FruitSelectDropdown: FC<FruitProps> = ({ fruitDetector }) => {
                    const [currentFruit, setCurrentFruit] = useState(fruitDetector)
                    
                    const changeFruit = (newFruit: string): void => {
                      setCurrentFruit(newFruit)
                    }
                    
                    return (
                      <form>
                        <select 
                          onChange={(event) => changeFruit(event.target.value)}
                          value={currentFruit}
                        >
                          <option value="apples">Red Apples</option>
                          <option value="oranges">Outrageous Oranges</option>
                          <option value="tomatoes">Technically a Fruit Tomatoes</option>
                          <option value="bananas">Bodacious Bananas</option>
                        </select>
                      </form>
                    )
                  }
                  

                  然后将FruitSelectDropdown 导入应用中的其他位置

                  import React, { FC } from 'react'
                  import { FruitSelectDropdown } from '../path/to/FruitSelectDropdown'
                  
                  const App: FC = () => {
                    return (
                      <div className="page-container">
                        <h1 className="header">A webpage about fruit</h1>
                        <div className="section-container">
                          <h2>Pick your favorite fruit</h2>
                          <FruitSelectDropdown fruitDetector='bananas' />
                  
                        </div>
                      </div>
                    )
                  }
                  
                  export default App
                  

                  奖金回合:选择当前值的翻译下拉菜单:

                  import React, { FC, useState } from 'react'
                  import { useTranslation } from 'react-i18next'
                  
                  export const LanguageSelectDropdown: FC = () => {
                    const { i18n } = useTranslation()
                    const i18nLanguage = i18n.language
                    const [currentI18nLanguage, setCurrentI18nLanguage] = useState(i18nLanguage)
                    
                    const changeLanguage = (language: string): void => {
                      i18n.changeLanguage(language)
                      setCurrentI18nLanguage(language)
                    }
                    
                    return (
                      <form>
                        <select 
                          onChange={(event) => changeLanguage(event.target.value)}
                          value={currentI18nLanguage}
                        >
                          <option value="en">English</option>
                          <option value="de">Deutsch</option>
                          <option value="es">Español</option>
                          <option value="fr">Français</option>
                        </select>
                      </form>
                    )
                  }
                  

                  An invaluable resource for React/Typescript

                  【讨论】:

                    【解决方案14】:

                    如果你使用无状态,那么

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

                    【讨论】:

                    【解决方案15】:
                    if you store objects in a state.
                    
                    class Studentinformation extends Component
                    {
                        constructor(props)
                     {
                       super(props);
                       this.handlechange=this.handlechange.bind(this);
                       this.handleSubmit=this.handleSubmit.bind(this);
                       
                       this.state={Studentinfo:{
                              Name:'',
                              Skill:'Java',
                              Address:''
                            }};
                     }
                     handlechange(event)
                     {
                       const name=event.target.name;
                       const value=event.target.value;
                    
                       this.setState({ Studentinfo:
                      {
                        ...this.state.Studentinfo,
                        [name]:[value]
                      }});
                     }
                     handleSubmit(event)
                     {
                      event.preventDefault();
                     }
                     render(){
                       return (
                      <div>
                        <form onSubmit={this.handleSubmit}>
                          <label>Name: <input type="text" name="Name" value={this.state.Studentinfo.Name} onChange={this.handlechange}></input></label>
                          <br/>
                          <label>Skills: 
                            <select value={this.state.Studentinfo.Skill} name="Skill" onChange={this.handlechange}>
                              <option value="C++" >C++</option>
                              <option value="C#">C#</option>
                              <option  value="Java">Java</option>
                            </select>
                            </label>
                            <br/>
                            <textarea value={this.state.Studentinfo.Address} onChange={this.handlechange}/>
                            <br/>
                          <input type="submit" value="Submit"></input>
                        </form>
                      </div>
                       );
                     }
                    
                    }
                    

                    【讨论】:

                    • 您好,如何提高最佳响应?那也是较短的
                    猜你喜欢
                    • 2021-08-17
                    • 2020-01-25
                    • 2020-07-17
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-09-02
                    • 2023-03-14
                    相关资源
                    最近更新 更多