React で <select> を使いたいけどちょっと困った話
constructor
で
this.state({value: ''});
としておいて、 render
で
render () { const hoge = [{name: 'test'}]; // セレクトボックスの選択候補となる要素。実際には Redux で管理していて store.getState().hoge みたいにしてとってくることを想定。状況によって値が変わる const options = hoge.map(e => { return <option value={e.name} key={e.name}>{e.name}</option>; }); return ( <select value={this.state.value} size="3" onChange={this.handleChange}> {options} </select> ); }
みたいにすると、初期状態で「test」という選択肢だけが存在するセレクトボックスが表示されますが、この「test」をクリックしても onChange
が発火しません。
this.state.value
が空文字列のまんま更新されず、困っておりました。
React の公式ドキュメントの <select>
の項目 Forms - React を見ると、
this.state = {value: 'coconut'};
と初期値を constructor
内で設定していますが、自分の例で言うところの options
はその時々で中身が変わるため、初期値をハードコードすることもできない状況です。
対処法がないものかと考えて、componentWillReceiveProps
を使って this.state.value
に options
の先頭要素を突っ込んでしまうというのを思いつきました。
componentWillReceiveProps() { const { hoge } = store.getState(); // hoge には [{name: 'test'}] が入ると想定 if (hoge.length > 0) { this.setState({ value: hoge[0].name, }); } }
みたいな感じです。こうすればレンダリングされるときには this.state.value
に hoge.name
が入っているので、submit するなりなんなりできます。
もっと賢い解決方法があったら知りたいですが、とりあえずこれで所望の挙動は得られました。