<p dir="auto">Consider the following example (live at <a href="http://www.webpackbin.com/Vk0Q_FqmZ" rel="nofollow">http://www.webpackbin.com/Vk0Q_FqmZ</a> with React 15.0.1):</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const MySelect = (props) =&gt; (
  &lt;select value={this.props.value} onChange={this.props.onChange}&gt;
    &lt;option value=&quot;fruit&quot;&gt;banana&lt;/option&gt;
    &lt;option value=&quot;vegetable&quot;&gt;broccoli&lt;/option&gt;
    &lt;option value=&quot;fruit&quot;&gt;orange&lt;/option&gt;
    &lt;option value=&quot;vegetable&quot;&gt;tomato&lt;/option&gt;
  &lt;/select&gt;
);

class App extends React.Component {
  constructor() {
    super()
    this.state = {}
    this.onSelectChange = this.onSelectChange.bind(this)
  }

  onSelectChange(e) {
    this.setState({ selectedValue: e.target.value })
  }

  render() {
    return &lt;MySelect 
      value={this.state.selectedValue} 
      onChange={this.onSelectChange}
    /&gt;
  }
}"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-v">MySelect</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">props</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span>
  <span class="pl-c1">&lt;</span><span class="pl-ent">select</span> <span class="pl-c1">value</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">value</span><span class="pl-kos">}</span> <span class="pl-c1">onChange</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">onChange</span><span class="pl-kos">}</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">option</span> <span class="pl-c1">value</span><span class="pl-c1">=</span><span class="pl-s">"fruit"</span><span class="pl-c1">&gt;</span>banana<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">option</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">option</span> <span class="pl-c1">value</span><span class="pl-c1">=</span><span class="pl-s">"vegetable"</span><span class="pl-c1">&gt;</span>broccoli<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">option</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">option</span> <span class="pl-c1">value</span><span class="pl-c1">=</span><span class="pl-s">"fruit"</span><span class="pl-c1">&gt;</span>orange<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">option</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">option</span> <span class="pl-c1">value</span><span class="pl-c1">=</span><span class="pl-s">"vegetable"</span><span class="pl-c1">&gt;</span>tomato<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">option</span><span class="pl-c1">&gt;</span>
  <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">select</span><span class="pl-c1">&gt;</span>
<span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">class</span> <span class="pl-v">App</span> <span class="pl-k">extends</span> <span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-c1">Component</span> <span class="pl-kos">{</span>
  <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">super</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">state</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">onSelectChange</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">onSelectChange</span><span class="pl-kos">.</span><span class="pl-en">bind</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">)</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">onSelectChange</span><span class="pl-kos">(</span><span class="pl-s1">e</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">setState</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">selectedValue</span>: <span class="pl-s1">e</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">value</span> <span class="pl-kos">}</span><span class="pl-kos">)</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">render</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-c1">&lt;</span><span class="pl-v">MySelect</span> 
      <span class="pl-c1">value</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">state</span><span class="pl-kos">.</span><span class="pl-c1">selectedValue</span><span class="pl-kos">}</span> 
      <span class="pl-c1">onChange</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">onSelectChange</span><span class="pl-kos">}</span>
    <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">HTML itself doesn't seem to have any problems with duplicate values in the <code class="notranslate">&lt;select&gt;</code> tag. As you can see in the example above, there are semantically valid reasons you might want to do this.</p>
<p dir="auto">But this controlled component example makes it impossible to select e.g. "orange" or "tomato": the selection will be forced to the first matching value.</p>
<p dir="auto">I thought about a solution that stores both the <code class="notranslate">selectedValue</code> and the <code class="notranslate">selectedIndex</code>, but react-dom's <code class="notranslate">&lt;select&gt;</code> does not take any sort of index prop, so I'd have to manipulate the internal DOM node, which I'm sure is bad form.</p>
<p dir="auto">React <em>could</em> be enhanced to take a <code class="notranslate">selectedIndex</code>, but I foresee problems with single source of truth.</p>
<p dir="auto">The fruit/vegetable example is a bit contrived, and there may not be many real-world scenarios you would want to do this in. My gut feeling is this should be a warning so developers (like me) don't paint themselves into a corner trying to support this case.</p>
<p dir="auto">It seems the <code class="notranslate">ref</code> callback isn't behaving as I expected it to, based on the docs.</p>
<p dir="auto">The docs say that <code class="notranslate">ref</code> is called when the component is mounted (and all the other times it's called, it's called with <code class="notranslate">null</code> as a parameter). However, when I put a <code class="notranslate">console.log</code> in <code class="notranslate">componentDidMount</code>, and one in the <code class="notranslate">ref</code> callback, the one in the <code class="notranslate">ref</code> callback is called on every <code class="notranslate">render()</code>, whereas the <code class="notranslate">componentDidMount</code> is only called once. The component i'm reffing isn't even changing props.</p>
<p dir="auto">Am I misunderstanding something? I'm using React 0.14.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var Value = React.createClass({
    componentDidMount() {
        console.log(&quot;Mounted&quot;);
    },
    render() {
        return &lt;div&gt;Dummy&lt;/div&gt;;
    }
});

var Hello = React.createClass({
  getInitialState() {
    return { value: 0 };
  },

  componentDidMount () {
     setInterval(() =&gt; { this.setState({value: this.state.value + 1})}, 1000);
  },

  render: function() {
    return (
        &lt;div&gt;
        &lt;span&gt;{this.state.value}&lt;/span&gt;
        &lt;Value ref={(e) =&gt; { if (e) { console.log(&quot;ref&quot;, e); }}} /&gt;
      &lt;/div&gt;
    );
  }
});

ReactDOM.render(&lt;Hello/&gt;, document.getElementById('container'));"><pre class="notranslate"><code class="notranslate">var Value = React.createClass({
    componentDidMount() {
        console.log("Mounted");
    },
    render() {
        return &lt;div&gt;Dummy&lt;/div&gt;;
    }
});

var Hello = React.createClass({
  getInitialState() {
    return { value: 0 };
  },

  componentDidMount () {
     setInterval(() =&gt; { this.setState({value: this.state.value + 1})}, 1000);
  },

  render: function() {
    return (
        &lt;div&gt;
        &lt;span&gt;{this.state.value}&lt;/span&gt;
        &lt;Value ref={(e) =&gt; { if (e) { console.log("ref", e); }}} /&gt;
      &lt;/div&gt;
    );
  }
});

ReactDOM.render(&lt;Hello/&gt;, document.getElementById('container'));
</code></pre></div>