はじめてのReact #11「フォームと連動する」プルダウン編

  • このエントリーをはてなブックマークに追加
  • LINEで送る

前回のテキストボックスに続き、今回はプルダウン(<select>)の操作方法になります。
ほぼ同じやり方で<ul>, <ol>などのリストにも適用できます。

メンバーリストComponent

メンバーの一覧をプルダウンとして表示し、名前をクリックすると削除されるComponentです。公式ドキュメントの「Lists and Keys」のサンプルコードを参考にしています。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>MemberList</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>

  <script type="text/babel">
   class MemberList extends React.Component {
     constructor(props) {
       super(props);
       this.state = {
          guys: props.guys
       };

       this.handleRemove = this.handleRemove.bind(this);
     }

     handleRemove(id){
       const guys = this.state.guys;
       const new_guys = [];

         for( let i=0; i<guys.length; i++ ){
           if(guys[i].id !== id){
             new_guys.push(guys[i]);
           }
       }

       this.setState({guys:new_guys});
     }

     render(){
       const guys = this.state.guys;
       const listItems = guys.map((guy) =>
         <option key={guy.id.toString()} onClick={ ()=>{ this.handleRemove(guy.id) } }>
           {guy.name}
         </option>
       );

       return <select size="3">{listItems}</select>;
     }
   }


    const guys = [
      {id:10, name:"Foo"},
      {id:20, name:"Bar"},
      {id:30, name:"Hoge"}
    ];

    ReactDOM.render(
      <MemberList guys={guys} />,
      document.getElementById('root')
    );
  </script>
</body>
</html>
- Sponsored Link -

実行結果

プルダウンはブラウザの拡大機能で大きくしています。クリックするとその要素が削除されるのがわかります。

解説

要素を作成する

mapメソッドで要素を作成する

render()内でプルダウンを作成しています。ここではReactではなくJavaScriptに搭載されているmapメソッドで配列の要素に対し順番に処理を施し、最終結果を変数listItemsへ返却しています。

  const listItems = guys.map((guy) =>
    <option key={guy.id.toString()} onClick={ ()=>{ this.handleRemove(guy.id) } }>
      {guy.name}
    </option>
  );

この配列に対しmapで処理を回していくのは、React使いの間ではよくやる手法だそうです。
わかりづらい場合は簡単なサンプルを実行してみると良いかと思います。

let array1 = [1,2,3];
let map1   = array1.map( (x)=>{ return( x + 1 ) } );

console.log(map1); // [2, 3, 4] が出力される

key属性

ここで新たにkey属性が登場しています。これはリストなどの複数の要素を作成する際にReactが要求してくる物で、各要素で重複しないユニークな値をつけてあげる必要があります。付けない場合は実行時エラーとなります。

react.development.js:316 Warning: Each child in an array or iterator should have a unique "key" prop.

Reactは内部でこのkeyを参照しながら、render()時に最小限の更新となるよう工夫をしているようです。パフォーマンスに関わるところだったんですね。

初期値を変更する

HTMLで言うところのselectedの値を指定するには、render()で返却しているJSXの<select>要素にdefaultValue属性を記述します。以下のようにすると2番目の要素が選択された状態で表示されます。

  return <select size="3" defaultValue="Bar">{listItems}</select>;

選択されている値を動的に管理する

前述のdefaultValueは動的に管理しないプルダウンの初期値を設定する物です。Stateなどに入れて管理する場合はvalueを使用します。以下のコードではPropsからもらってきた値をStateに入れ、プルダウンの値が変更されたらonChangeイベントで拾ってStateの更新を行っています。

class MemberList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
        guys: this.props.guys,
       value: this.props.default     //Propsとしてもらってきた値を入れる
    };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e){
    this.setState({value:e.target.value});
  }

  render(){
    const guys = this.state.guys;
    const listItems = guys.map((guy) =>
      <option key={guy.id.toString()}>
        {guy.name}
      </option>
    );

    // valueで動的に'selected'の要素を指定
    return <select size="3" value={this.state.value}>{listItems}</select>;
  }
}

const guys = [
  {id:10, name:"Foo"},
  {id:20, name:"Bar"},
  {id:30, name:"Hoge"}
];

ReactDOM.render(
  <MemberList guys={guys} default="Bar" />,    //selectedの値を指定
  document.getElementById('root')
);

なおonChangeイベントを未定義だと以下のように実行時エラーが発生してしまいますのでご注意を。

react-dom.development.js:3102 Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

書籍

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)
穴井 宏幸 石井 直矢 柴田 和祈 三宮 肇
翔泳社
売り上げランキング: 139,067

参考ページ


- Sponsored Link -

同じカテゴリの記事

Donate

投げ銭お待ちしております!

BTC3A9nH1j7qQdKrSTrmnEdweo6zPqpHBmkxC
ETH0x1aE0541198D1F9f2908a25C35032A473e74D3731
XPXaQ9zv65F9ovfoMBrFGiPRG47aSHFhy8SX
MONAMTKgzSiS5BDueZkRCHySih24TGFwHThaDQ (MonaCoin)
ZNYZhnpf4RFYVQTAQiyoJg9dGoeC4bgT3BoSy (BitZeny)

ご質問やリクエストなどお気軽に。メールアドレスの入力は任意です。書き込みが反映されるまで時間がかかります。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください