React JSX:選択された<select>オプションで「selected」を選択


403

<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

回答:


649

Reactはこの目的のためにブール値を自動的に理解するので、簡単に書くことができます(注:非推奨)

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

そして、「選択された」を適切に出力します。

しかし、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 select tag docをご覧ください。


56
現在のバージョンのReact(0.9)では、オプションで選択した属性を設定してもまったく機能しません。代わりに、select要素のvalue属性を設定してください。
liammclennan 2014

2
ajax.defaultValueでデータをロードすると機能しません。値は機能していますが、選択リストの別の項目を選択できません。リストは開いていますが、それらの1つを選択すると、値の項目が選択されます。
user1924375

5
@ user1924375次のように、onChangeイベントonChange={this.handleSelect}を使用してコンポーネントの状態値を設定する必要があります。例: 'handleSelect:function(){this.setState({value:event.target.value});} `これにより、selectコンポーネントが新しい選択したアイテム。それがあなたを助けることを願っています。
funnydaredevil 2015年

1
まだドキュメント化されていませんが、有効になっている場合は、value上のプロップを<select>配列にすることがmultiselectできます。
tirdadc 2017

4
むしろdefaultValue初期化に使用する
dewwwald

70

の "selected"プロパティを設定しようとすると、Reactが警告することを実行できます<option>

on に設定する代わりに、defaultValueまたはvaluepropsを使用します。<select>selected<option>

だから、あなたが使用することができますoptions.value上のdefaultValueあなたの選択の


9
現在選択されているオプションを引き続き表示したい場合は、どうすればよいですか?現在実際にオプションを選択したままにできる(そして将来のPOSTのためにフォームの状態を維持できる)唯一の方法は、select = trueを設定することです。select要素のdefaultValueおよびvalueプロパティを設定しようとしましたが、オプションメニューで正しいオプションを選択済みに設定しても、ビューにレンダリングされません。何かアドバイス?
The Pied Pipes

4
例多分??
しんぞう2018年

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)
シェーバーは

...の意味を自分に尋ねる私のようなあなたのために:reactjs.org/docs/jsx-in-depth.html#spread-attributes
talsibony

@talsibony-それは確かにスプレッド演算子ですが、私のサンプルコードでは、ここに他のコードを挿入するだけです
アンディ・ローレンツ2017

@AndyLorenzその場合、私はそれを削除することをお勧めします... :)、または//コードの残りのようなコメントを書く
talsibony

8

これを行う方法の最新の例を次に示します。ドキュメント反応し、プラス自動結合「脂肪矢印」メソッドの構文は。

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

4

選択タグの最初のオプションとして追加するだけです:

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

これがデフォルトになり、有効なオプションを選択すると、州に設定されます


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>に更新されないという問題がありました。私の問題は、2回連続でレンダリングする場合、最初は事前選択なしで<option>、2回目は1つを事前選択せずに、<select>いないタグは2番目のレンダリングで更新されず、最初のデフォルトのままになるということです。

私は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" ...

マウントするまでプロップが存在しない場合、コンパイル時のエラーを回避します。


それは本当に問題を解決していません。これが表示されます:警告:失敗したプロップタイプ:ハンドラーvalueなしでフォームフィールドにプロップを提供しましたonChange。これにより、読み取り専用フィールドがレンダリングされます。フィールドを変更可能にする必要がある場合defaultValue。それ以外の場合は、onChangeまたはを設定しますreadOnly
Jason Rice
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.