Change:
If the contents of the element is constructed in special way, it breaks React on component update with "Unable to find element" error. Here's an example of method body: Here's working jsfiddle (with React 0.12.0): Adding to option props fixes the issue.
React separates the 's children with s. In HTML only text is allowed there and the browser handles it gracefully by removing the s. On the next render React tries to change those s, but can't find them. A workaround is to give a string to the :
Thanks for explaining this. In such case probably the best solution would be to extend error explanation with information about "option" elements (behind "table" etc).
Yea, we should probably do some checks in our ReactDOMOption wrapper and not allow anything but text as children.
Just hit this
This can be fixed by using ReactChildren.forEach in ReactDOMOption to flatten the children before passing it to the raw HTML component. Strings and numbers get concatted together; other elements should be skipped and log a warning for invalid children.

Discussion:
'use strict'; var ReactBrowserComponentMixin = require('ReactBrowserComponentMixin'); <ins> var ReactChildren = require('ReactChildren'); </ins> var ReactClass = require('ReactClass'); var ReactDOMSelect = require('ReactDOMSelect'); var ReactElement = require('ReactElement');

props = assign({}, props, {selected: this.state.selected}); } <del> return option(props, this.props.children); </del> <ins> var content = ''; // Flatten children and warn if they aren't strings or numbers; // invalid types are ignored. ReactChildren.forEach(this.props.children, function(child) { if (child == null) { return; } if (typeof child === 'string' || typeof child === 'number') { content += child; } else { warning( false, 'Only strings and numbers are supported as <option> children.' ); } }); return option(props, content); </ins> } });

<ins> /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @emails react-core */ 'use strict'; /*jshint evil:true */ describe('ReactDOMOption', function() { var React; var ReactTestUtils; beforeEach(function() { React = require('React'); ReactTestUtils = require('ReactTestUtils'); }); it('should flatten children to a string', function() { var stub = <option>{1} {'foo'}</option>; stub = ReactTestUtils.renderIntoDocument(stub); var node = React.findDOMNode(stub); expect(node.innerHTML).toBe('1 foo'); }); it('should ignore invalid children types', function() { var stub = <option>{1} <div /> {2}</option>; stub = ReactTestUtils.renderIntoDocument(stub); var node = React.findDOMNode(stub); expect(node.innerHTML).toBe('1  2'); }); it('should warn when passing invalid children', function() { var stub = <option>{1} <div /></option>; spyOn(console, 'error'); stub = ReactTestUtils.renderIntoDocument(stub); var node = React.findDOMNode(stub); expect(console.error.calls.length).toBe(1); expect(console.error.calls[0].args[0]).toContain( 'Only strings and numbers are supported as <option> children.' ); }); it('should ignore null/undefined/false children without warning', function() { var stub = <option>{1} {false}{true}{null}{undefined} {2}</option>; spyOn(console, 'error'); stub = ReactTestUtils.renderIntoDocument(stub); var node = React.findDOMNode(stub); expect(console.error.calls.length).toBe(0); expect(node.innerHTML).toBe('1  2'); }); }); </ins>