Question:
The same in Chrome 35.0.1916.153. It's OK in Chrome Canary 38.0.2082.0 canary (64-bit).
This is actually an - we've the workarounds to make sure disabled s actually behave correctly here. This holds for all disabled inputs it seems.

<ins> /** * Copyright 2013-present, 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. * * @providesModule DisabledInputUtils */ 'use strict'; var disableableMouseListenerNames = { onClick: true, onDoubleClick: true, onMouseDown: true, onMouseMove: true, onMouseUp: true, onClickCapture: true, onDoubleClickCapture: true, onMouseDownCapture: true, onMouseMoveCapture: true, onMouseUpCapture: true, }; /** * Implements a native component that does not receive mouse events * when `disabled` is set. */ var DisabledInputUtils = { getNativeProps: function(inst, props) { if (!props.disabled) { return props; } // Copy the props, except the mouse listeners var nativeProps = {}; for (var key in props) { if (!disableableMouseListenerNames[key] && props.hasOwnProperty(key)) { nativeProps[key] = props[key]; } } return nativeProps; }, }; module.exports = DisabledInputUtils; </ins>

'use strict'; <del> var mouseListenerNames = { onClick: true, onDoubleClick: true, onMouseDown: true, onMouseMove: true, onMouseUp: true, onClickCapture: true, onDoubleClickCapture: true, onMouseDownCapture: true, onMouseMoveCapture: true, onMouseUpCapture: true, }; </del> <ins> var DisabledInputUtils = require('DisabledInputUtils'); </ins> /** * Implements a <button> native component that does not receive mouse events * when `disabled` is set. */ var ReactDOMButton = { <del> getNativeProps: function(inst, props) { if (!props.disabled) { return props; } // Copy the props, except the mouse listeners var nativeProps = {}; for (var key in props) { if (props.hasOwnProperty(key) && !mouseListenerNames[key]) { nativeProps[key] = props[key]; } } return nativeProps; }, </del> <ins> getNativeProps: DisabledInputUtils.getNativeProps, </ins> }; module.exports = ReactDOMButton;

// Make sure we set .type before any other properties (setting .value // before .type means .value is lost in IE11 and below) type: undefined, <del> }, props, { </del> <ins> }, DisabledInputUtils.getNativeProps(inst, props), { </ins> defaultChecked: undefined, defaultValue: undefined, value: value != null ? value : inst._wrapperState.initialValue,

'use strict'; <ins> var DisabledInputUtils = require('DisabledInputUtils'); </ins> var LinkedValueUtils = require('LinkedValueUtils'); var ReactDOMComponentTree = require('ReactDOMComponentTree'); var ReactUpdates = require('ReactUpdates');

*/ var ReactDOMSelect = { getNativeProps: function(inst, props) { <del> return Object.assign({}, props, { </del> <ins> return Object.assign({}, DisabledInputUtils.getNativeProps(inst, props), { </ins> onChange: inst._wrapperState.onChange, value: undefined, });

'use strict'; <ins> var DisabledInputUtils = require('DisabledInputUtils'); </ins> var DOMPropertyOperations = require('DOMPropertyOperations'); var LinkedValueUtils = require('LinkedValueUtils'); var ReactDOMComponentTree = require('ReactDOMComponentTree');

// Always set children to the same thing. In IE9, the selection range will // get reset if `textContent` is mutated. <del> var nativeProps = Object.assign({}, props, { </del> <ins> var nativeProps = Object.assign({}, DisabledInputUtils.getNativeProps(inst, props), { </ins> defaultValue: undefined, value: undefined, children: inst._wrapperState.initialValue,

<ins> /** * Copyright 2013-present, 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'; describe('DisabledInputUtils', function() { var React; var ReactDOM; var ReactTestUtils; var elements = ['button', 'input', 'select', 'textarea']; function expectClickThru(element) { onClick.mockClear(); ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(element)); expect(onClick.mock.calls.length).toBe(1); } function expectNoClickThru(element) { onClick.mockClear(); ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(element)); expect(onClick.mock.calls.length).toBe(0); } function mounted(element) { element = ReactTestUtils.renderIntoDocument(element); return element; } var onClick = jest.genMockFn(); elements.forEach(function(tagName) { describe(tagName, function() { beforeEach(function() { React = require('React'); ReactDOM = require('ReactDOM'); ReactTestUtils = require('ReactTestUtils'); }); it('should forward clicks when it starts out not disabled', function() { var element = React.createElement(tagName, { onClick: onClick, }); expectClickThru(mounted(element)); }); it('should not forward clicks when it starts out disabled', function() { var element = React.createElement(tagName, { onClick: onClick, disabled: true, }); expectNoClickThru(mounted(element)); }); it('should forward clicks when it becomes not disabled', function() { var container = document.createElement('div'); var element = ReactDOM.render( React.createElement(tagName, { onClick: onClick, disabled: true }), container ); element = ReactDOM.render( React.createElement(tagName, { onClick: onClick }), container ); expectClickThru(element); }); it('should not forward clicks when it becomes disabled', function() { var container = document.createElement('div'); var element = ReactDOM.render( React.createElement(tagName, { onClick: onClick }), container ); element = ReactDOM.render( React.createElement(tagName, { onClick: onClick, disabled: true }), container ); expectNoClickThru(element); }); it('should work correctly if the listener is changed', function() { var container = document.createElement('div'); var element = ReactDOM.render( React.createElement(tagName, { onClick: onClick, disabled: true }), container ); element = ReactDOM.render( React.createElement(tagName, { onClick: onClick, disabled: false }), container ); expectClickThru(element); }); }); }); }); </ins>

<del> /** * Copyright 2013-present, 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'; describe('ReactDOMButton', function() { var React; var ReactDOM; var ReactTestUtils; var onClick = jest.genMockFn(); function expectClickThru(button) { onClick.mockClear(); ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(button)); expect(onClick.mock.calls.length).toBe(1); } function expectNoClickThru(button) { onClick.mockClear(); ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(button)); expect(onClick.mock.calls.length).toBe(0); } function mounted(button) { button = ReactTestUtils.renderIntoDocument(button); return button; } beforeEach(function() { React = require('React'); ReactDOM = require('ReactDOM'); ReactTestUtils = require('ReactTestUtils'); }); it('should forward clicks when it starts out not disabled', function() { expectClickThru(mounted(<button onClick={onClick} />)); }); it('should not forward clicks when it starts out disabled', function() { expectNoClickThru( mounted(<button disabled={true} onClick={onClick} />) ); }); it('should forward clicks when it becomes not disabled', function() { var container = document.createElement('div'); var btn = ReactDOM.render( <button disabled={true} onClick={onClick} />, container ); btn = ReactDOM.render( <button onClick={onClick} />, container ); expectClickThru(btn); }); it('should not forward clicks when it becomes disabled', function() { var container = document.createElement('div'); var btn = ReactDOM.render( <button onClick={onClick} />, container ); btn = ReactDOM.render( <button disabled={true} onClick={onClick} />, container ); expectNoClickThru(btn); }); it('should work correctly if the listener is changed', function() { var container = document.createElement('div'); var btn = ReactDOM.render( <button disabled={true} onClick={function() {}} />, container ); btn = ReactDOM.render( <button disabled={false} onClick={onClick} />, container ); expectClickThru(btn); }); }); </del>


Question: I'll let write these, but it would be nice to get them spot checked by and/or

title: Immutability Helpers - id: pure-render-mixin title: PureRenderMixin <ins> - id: perf title: Performance Tools </ins> - title: Reference items: - id: top-level-api

layout: docs permalink: pure-render-mixin.html prev: update.html <ins> next: perf.html </ins> --- If your React component's render function is "pure" (in other words, it renders the same result given the same props and state), you can use this mixin for a considerable performance boost.

<ins> --- id: perf title: Performance Tools layout: docs permalink: perf.html prev: pure-render-mixin.html --- React is usually quite fast out of the box. However, in situations where you need to squeeze every ounce of performance out of your app, it provides a [shouldComponentUpdate](/react/docs/component-specs.html#updating-shouldcomponentupdate) hook where you can add optimization hints to React's diff algorithm. In addition to giving you an overview of your app's overall performance, ReactPerf is a profiling tool that tells you exactly where you need to put these hooks. > Note: > > The dev build of React is slower than the prod build, due to all the extra logic for providing, for example, React's friendly console warnings (stripped away in the prod build). Therefore, the profiler only serves to indicate the _relatively_ expensive parts of your app. ## General API ### `Perf.start()` and `Perf.stop()` Start/stop the measurement. The React operations in-between are recorded for analyses below. Operations that took an insignificant amount of time are ignored. ### `Perf.printInclusive(measurements)` Prints the overall time taken. If no argument's passed, defaults to all the measurements from the last recording. This prints a nicely formatted table in the console, like so: ![](/react/img/docs/perf-inclusive.png) ### `Perf.printExclusive(measurements)` "Exclusive" times don't include the times taken to mount the components: processing props, `getInitialState`, call `componentWillMount` and `componentDidMount`, etc. ![](/react/img/docs/perf-exclusive.png) ### `Perf.printWasted(measurements)` **The most useful part of the profiler**. "Wasted" time is spent on components that didn't actually render anything, e.g. the render stayed the same, so the DOM wasn't touched. ![](/react/img/docs/perf-wasted.png) ### `Perf.printDOM(measurements)` Prints the underlying DOM manipulations, e.g. "set innerHTML" and "remove". ![](/react/img/docs/perf-dom.png) ## Advanced API The above print methods use `Perf.getLastMeasurements()` to pretty-print the result. ### `Perf.getLastMeasurements()` Get the measurements array from the last start-stop session. The array contains objects, each of which looks like this: ```js { // The term "inclusive" and "exclusive" are explained below "exclusive": {}, // '.0.0' is the React ID of the node "inclusive": {".0.0": 0.0670000008540228, ".0": 0.3259999939473346}, "render": {".0": 0.036999990697950125, ".0.0": 0.010000003385357559}, // Number of instances "counts": {".0": 1, ".0.0": 1}, // DOM touches "writes": {}, // Extra debugging info "displayNames": { ".0": {"current": "App", "owner": "<root>"}, ".0.0": {"current": "Box", "owner": "App"} }, "totalTime": 0.48499999684281647 } ``` </ins>


Question: This logs both and : This seems weird to me and inconsistent with the behavior for non-static functions. Can we change this to give an error too?

continue; } <ins> var isReserved = name in RESERVED_SPEC_KEYS; invariant( !isReserved, 'ReactCompositeComponent: You are attempting to define a reserved ' + 'property, `%s`, that shouldn't be on the "statics" key. Define it ' + 'as an instance property instead; it will still be accessible on the ' + 'constructor.', name ); </ins> var isInherited = name in Constructor; <del> var result = property; if (isInherited) { var existingProperty = Constructor[name]; var existingType = typeof existingProperty; var propertyType = typeof property; invariant( existingType === 'function' && propertyType === 'function', 'ReactCompositeComponent: You are attempting to define ' + '`%s` on your component more than once, but that is only supported ' + 'for functions, which are chained together. This conflict may be ' + 'due to a mixin.', name ); result = createChainedFunction(existingProperty, property); } Constructor[name] = result; </del> <ins> invariant( !isInherited, 'ReactCompositeComponent: You are attempting to define ' + '`%s` on your component more than once. This conflict may be ' + 'due to a mixin.', name ); Constructor[name] = property; </ins> } }

expect(Component.pqr()).toBe(Component.type); }); <ins> it('should throw if a reserved property is in statics', function() { expect(function() { React.createClass({ statics: { getDefaultProps: function() { return { foo: 0 }; } }, render: function() { return <span />; } }); }).toThrow( 'Invariant Violation: ReactCompositeComponent: You are attempting to ' + 'define a reserved property, `getDefaultProps`, that shouldn't be on ' + 'the "statics" key. Define it as an instance property instead; it ' + 'will still be accessible on the constructor.' ); }); </ins> it('should support statics in mixins', function() { var Mixin = { statics: {

}); }).toThrow( 'Invariant Violation: ReactCompositeComponent: You are attempting to ' + <del> 'define `abc` on your component more than once, but that is only ' + 'supported for functions, which are chained together. This conflict ' + 'may be due to a mixin.' </del> <ins> 'define `abc` on your component more than once. This conflict may be ' + 'due to a mixin.' ); }); it("should throw if mixins override functions in statics", function() { expect(function() { var Mixin = { statics: { abc: function() { console.log('foo'); } } }; React.createClass({ mixins: [Mixin], statics: { abc: function() { console.log('bar'); } }, render: function() { return <span />; } }); }).toThrow( 'Invariant Violation: ReactCompositeComponent: You are attempting to ' + 'define `abc` on your component more than once. This conflict may be ' + 'due to a mixin.' </ins> ); });


Question:
Right now, we copy it in one of the hottest paths of React to allow users to mutate the style object afterward. I've come to realize that this pattern doesn't come up that often, since the style's often created inline inside and not retained after that. Additionally, is coming soon, so people could always clone the style themselves if there's the need.
You could start with a dev-only warning() if you're concerned about breaking stuff.
Would be extremely nice, especially since we're going to make a push to get more people to use inline styles in the future
Really? From my tests, it would seem that it would be a performance nightmare.
it's certainly nice if it was possible. I think there are some tricks to make this performant enough.

var invariant = require('invariant'); var isEventSupported = require('isEventSupported'); var keyOf = require('keyOf'); <ins> var shallowEqual = require('shallowEqual'); </ins> var validateDOMNesting = require('validateDOMNesting'); var warning = require('warning');

var ELEMENT_NODE_TYPE = 1; <ins> var styleMutationWarning = {}; function checkAndWarnForMutatedStyle(style1, style2, component) { if (style1 == null || style2 == null) { return; } if (shallowEqual(style1, style2)) { return; } var componentName = component._tag; var owner = component._currentElement._owner; var ownerName; if (owner) { ownerName = owner.getName(); } var hash = ownerName + '|' + componentName; if (styleMutationWarning.hasOwnProperty(hash)) { return; } styleMutationWarning[hash] = true; warning( false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` will be deprecated. Consider cloning it beforehand. ' + 'Check the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', JSON.stringify(style1), JSON.stringify(style2) ); } </ins> /** * Optionally injectable operations for mutating the DOM */

validateDangerousTag(tag); this._tag = tag; this._renderedChildren = null; <ins> this._previousStyle = null; </ins> this._previousStyleCopy = null; this._rootNodeID = null; }

} else { if (propKey === STYLE) { if (propValue) { <ins> if (__DEV__) { // See `_updateDOMProperties`. style block this._previousStyle = propValue; } </ins> propValue = this._previousStyleCopy = assign({}, props.style); } propValue = CSSPropertyOperations.createMarkupForStyles(propValue);

} if (propKey === STYLE) { if (nextProp) { <ins> if (__DEV__) { checkAndWarnForMutatedStyle( this._previousStyleCopy, this._previousStyle, this ); this._previousStyle = nextProp; } </ins> nextProp = this._previousStyleCopy = assign({}, nextProp); } if (lastProp) {

expect(stubStyle.fontFamily).toEqual(''); }); <ins> // TODO: (poshannessy) deprecate this pattern. </ins> it("should update styles when mutating style object", function() { <ins> // not actually used. Just to suppress the style mutation warning spyOn(console, 'error'); </ins> var styles = {display: 'none', fontFamily: 'Arial', lineHeight: 1.2}; var container = document.createElement('div'); React.render(<div style={styles} />, container);

expect(stubStyle.lineHeight).toBe(''); });  it('should warn when mutating style', function() { spyOn(console, 'error'); var style = {border: '1px solid black'}; var App = React.createClass({ getInitialState: function() { return {style: style}; }, render: function() { return
asd
; } }); var stub = ReactTestUtils.renderIntoDocument(<App />); style.position = 'absolute'; stub.setState({style: style}); expect(console.error.argsForCall.length).toBe(1); expect(console.error.argsForCall[0][0]).toEqual( 'Warning: `div` was passed a style object that has previously been ' + 'mutated. Mutating `style` will be deprecated. Consider cloning it ' + 'beforehand. Check the `render` of `App`. Previous style: ' + '{"border":"1px solid black"}. Mutated style: ' + '{"border":"1px solid black","position":"absolute"}.' ); style = {background: 'red'}; stub = ReactTestUtils.renderIntoDocument(<App />); style.background = 'green'; stub.setState({style: {background: 'green'}}); // already warned once for the same component and owner expect(console.error.argsForCall.length).toBe(1); style = {background: 'red'}; var div = document.createElement('div'); React.render(, div); style.background = 'blue'; React.render(, div); expect(console.error.argsForCall.length).toBe(2); });  it("should update styles if initially null", function() { var styles = null; var container = document.createElement('div');

expect(stubStyle.color).toEqual(''); }); <ins> // trouble </ins> it("should update styles when 'style' changes from null to object", function() { var container = document.createElement('div'); var styles = {color: 'red'};


Question:
We currently support this, but it makes code less understandable and we'd like to stop supporting it and encourage people to use either e.preventDefault() or e.stopPropagation() as appropriate.
:+1: And then free up the event handler's return value for something else.
you mean? :)
Maybe =) Otherwise we can always use it to indicate something in a potential future event system.

String type ``` <ins> > Note: > > As of v0.12, returning `false` from an event handler will no longer stop event propagation. Instead, `e.stopPropagation()` or `e.preventDefault()` should be triggered manually, as appropriate. </ins> ## Supported Events

onMouseMove onMouseOut onMouseOver onMouseUp ``` <del> Properties: </del> <ins> Properties: </ins> ```javascript boolean altKey

expect(idCallOrder[0]).toBe(getID(CHILD)); }); <del> it('should stopPropagation if false is returned', function() { </del> <ins> it('should stopPropagation if false is returned, but warn', function() { </ins> ReactBrowserEventEmitter.putListener( getID(CHILD), ON_CLICK_KEY,

ON_CLICK_KEY, recordID.bind(null, getID(GRANDPARENT)) ); <ins> spyOn(console, 'warn'); </ins> ReactTestUtils.Simulate.click(CHILD); expect(idCallOrder.length).toBe(1); expect(idCallOrder[0]).toBe(getID(CHILD)); <ins> expect(console.warn.calls.length).toEqual(1); expect(console.warn.calls[0].args[0]).toBe( 'Warning: Returning `false` from an event handler is deprecated and ' + 'will be ignored in a future release. Instead, manually call ' + 'e.stopPropagation() or e.preventDefault(), as appropriate.' ); </ins> }); /**

var invariant = require('invariant'); var keyOf = require('keyOf'); <ins> var warning = require('warning'); </ins> var topLevelTypes = EventConstants.topLevelTypes;

/** * Same as the default implementation, except cancels the event when return <del> * value is false. </del> <ins> * value is false. This behavior will be disabled in a future release. </ins> * * @param {object} Event to be dispatched. * @param {function} Application-level callback.

*/ executeDispatch: function(event, listener, domID) { var returnValue = EventPluginUtils.executeDispatch(event, listener, domID); <ins> warning( typeof returnValue !== 'boolean', 'Returning `false` from an event handler is deprecated and will be ' + 'ignored in a future release. Instead, manually call ' + 'e.stopPropagation() or e.preventDefault(), as appropriate.' ); </ins> if (returnValue === false) { event.stopPropagation(); event.preventDefault();


Question:
We're basically keeping 2 copies of documentation in sync and failing. We should just point at and We should maybe make the permalinks on our site redirect or just link offsite. We should also look for links in our docs pointing to those pages and update.
cc
also cc
Definitively agreed, we should link all the traffic to the dedicated website. See the Complementary section on Flux website

items: - id: flux-overview title: Flux Overview <ins> href: http://facebook.github.io/flux/docs/overview.html </ins> - id: flux-todo-list title: Flux TodoMVC Tutorial <ins> href: http://facebook.github.io/flux/docs/todo-list.html </ins>

 {% for item in section.items %}
   {{ item.title }}    {{ item | sidebar_item_link}}  {% if item.subitems %}
 {% for subitem in item.subitems %}
   {{ subitem.title }}    {{ item | sidebar_item_link}}
 {% endfor %}

module Jekyll module SidebarItemFilter def sidebar_item_link(item) pageID = @context.registers[:page]["id"] itemID = item["id"] href = item["href"] || "/react/docs/#{itemID}.html" className = pageID == itemID ? ' class="active"' : '' return "#{item["title"]}" end end end Liquid::Template.register_filter(Jekyll::SidebarItemFilter)

When a user interacts with a React view, the view sends an action (usually represented as a JavaScript object with some fields) through the dispatcher, which notifies the various stores that hold the application's data and business logic. When the stores change state, they notify the views that something has updated. This works especially well with React's declarative model, which allows the stores to send updates without specifying how to transition views between states. <del> Flux is more of a pattern than a formal framework, so you can start using Flux immediately without a lot of new code. An [example of this architecture](https://github.com/facebook/flux/tree/master/examples/flux-todomvc) is available, along with more [detailed documentation](http://facebook.github.io/react/docs/flux-overview.html) and a [tutorial](http://facebook.github.io/react/docs/flux-todo-list.html). Look for more examples to come in the future. </del> <ins> Flux is more of a pattern than a formal framework, so you can start using Flux immediately without a lot of new code. An [example of this architecture](https://github.com/facebook/flux/tree/master/examples/flux-todomvc) is available, along with more [detailed documentation](http://facebook.github.io/flux/docs/overview.html) and a [tutorial](http://facebook.github.io/flux/docs/todo-list.html). Look for more examples to come in the future. </ins>

--- id: flux-overview title: Flux Application Architecture  next: flux-todo-list.html  ---  Flux is the application architecture that Facebook uses for building client-side web applications.  It complements React's composable view components by utilizing a unidirectional data flow.  It's more of a pattern rather than a formal framework, and you can start using Flux immediately without a lot of new code.

 Flux applications have three major parts: the dispatcher, the stores, and the views (React components).  These should not be confused with Model-View-Controller.  Controllers do exist in a Flux application, but they are controller-views — views often found at the top of the hierarchy that retrieve data from the stores and pass this data down to their children.  Additionally, actions — dispatcher helper methods — are often used to support a semantic dispatcher API.  It can be useful to think of them as a fourth part of the Flux update cycle. Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with a React view, the view propagates an action through a central dispatcher, to the various stores that hold the application's data and business logic, which updates all of the views that are affected. This works especially well with React's declarative programming style, which allows the store to send updates without specifying how to transition views between states. We originally set out to deal correctly with derived data: for example, we wanted to show an unread count for message threads while another view showed a list of threads, with the unread ones highlighted. This was difficult to handle with MVC — marking a single thread as read would update the thread model, and then also need to update the unread count model.  These dependencies and cascading updates often occur in a large MVC application, leading to a tangled weave of data flow and unpredictable results. Control is inverted with stores: the stores accept updates and reconcile them as appropriate, rather than depending on something external to update its data in a consistent way. Nothing outside the store has any insight into how it manages the data for its domain, helping to keep a clear separation of concerns. This also makes stores more testable than models, especially since stores have no direct setter methods like `setAsRead()`, but instead have only an input point for the payload, which is delivered through the dispatcher and originates with actions. ## Structure and Data Flow Data in a Flux application flows in a single direction, in a cycle:
 Views ---> (actions) ----> Dispatcher ---> (registered callback) ---> Stores -------+ Ʌ                                                                                | |                                                                                V +-- (Controller-Views "change" event handlers) ---- (Stores emit "change" events) --+
 A unidirectional data flow is central to the Flux pattern, and in fact Flux takes its name from the Latin word for flow. In the above diagram, the dispatcher, stores and views are independent nodes with distinct inputs and outputs. The actions are simply discrete, semantic helper functions that facilitate passing data to the dispatcher. All data flows through the dispatcher as a central hub.  Actions most often originate from user interactions with the views, and are nothing more than a call into the dispatcher.  The dispatcher then invokes the callbacks that the stores have registered with it, effectively dispatching the data payload contained in the actions to all stores.  Within their registered callbacks, stores determine which actions they are interested in, and respond accordingly.  The stores then emit a "change" event to alert the controller-views that a change to the data layer has occurred.  Controller-views listen for these events and retrieve data from the stores in an event handler.  The controller-views call their own `render()` method via `setState()` or `forceUpdate()`, updating themselves and all of their children. This structure allows us to reason easily about our application in a way that is reminiscent of functional reactive programming, or more specifically data-flow programming or flow-based programming, where data flows through the application in a single direction — there are no two-way bindings. Application state is maintained only in the stores, allowing the different parts of the application to remain highly decoupled. Where dependencies do occur between stores, they are kept in a strict hierarchy, with synchronous updates managed by the dispatcher. We found that two-way data bindings led to cascading updates, where changing one object led to another object changing, which could also trigger more updates. As applications grew, these cascading updates made it very difficult to predict what would change as the result of one user interaction. When updates can only change data within a single round, the system as a whole becomes more predictable. Let's look at the various parts of the Flux update cycle up close. A good place to start is the dispatcher. ### A Single Dispatcher The dispatcher is the central hub that manages all data flow in a Flux application. It is essentially a registry of callbacks into the stores. Each store registers itself and provides a callback. When the dispatcher responds to an action, all stores in the application are sent the data payload provided by the action via the callbacks in the registry. As an application grows, the dispatcher becomes more vital, as it can manage dependencies between stores by invoking the registered callbacks in a specific order.  Stores can declaratively wait for other stores to finish updating, and then update themselves accordingly. ### Stores Stores contain the application state and logic. Their role is somewhat similar to a model in a traditional MVC, but they manage the state of many objects — they are not instances of one object. Nor are they the same as Backbone's collections. More than simply managing a collection of ORM-style objects, stores manage the application state for a particular __domain__ within the application. For example, Facebook's [Lookback Video Editor](https://facebook.com/lookback/edit) utilized a TimeStore that kept track of the playback time position and the playback state. On the other hand, the same application's ImageStore kept track of a collection of images.  The TodoStore in our [TodoMVC example](https://github.com/facebook/flux/tree/master/examples/flux-todomvc) is similar in that it manages a collection of to-do items.  A store exhibits characteristics of both a collection of models and a singleton model of a logical domain. As mentioned above, a store registers itself with the dispatcher and provides it with a callback. This callback receives the action's data payload as a parameter. The payload contains a type attribute, identifying the action's type. Within the store's registered callback, a switch statement based on the action's type is used to interpret the payload and to provide the proper hooks into the store's internal methods. This allows an action to result in an update to the state of the store, via the dispatcher. After the stores are updated, they broadcast an event declaring that their state has changed, so the views may query the new state and update themselves. ### Views and Controller-Views React provides the kind of composable views we need for the view layer. Close to the top of the nested view hierarchy, a special kind of view listens for events that are broadcast by the stores that it depends on. One could call this a controller-view, as it provides the glue code to get the data from the stores and to pass this data down the chain of its descendants. We might have one of these controller-views governing any significant section of the page. When it receives the event from the store, it first requests the new data it needs via the stores' public getter methods. It then calls its own `setState()` or `forceUpdate()` methods, causing its `render()` method and the `render()` method of all its descendants to run. We often pass the entire state of the store down the chain of views in a single object, allowing different descendants to use what they need. In addition to keeping the controller-like behavior at the top of the hierarchy, and thus keeping our descendant views as functionally pure as possible, passing down the entire state of the store in a single object also has the effect of reducing the number of props we need to manage. Occasionally we may need to add additional controller-views deeper in the hierarchy to keep components simple.  This might help us to better encapsulate a section of the hierarchy related to a specific  data domain.  Be aware, however, that controller-views deeper in the hierarchy can violate the singular flow of data by introducing a new, potentially conflicting entry point for the data flow.  In making the decision of whether to add a deep controller-view, balance the gain of simpler components against the complexity of multiple data updates flowing into the hierarchy at different points.  These multiple data updates can lead to odd effects, with React's render method getting invoked repeatedly by updates from different controller-views, potentially increasing the difficulty of debugging. ### Actions The dispatcher exposes a method that allows a view to trigger a dispatch to the stores, and to include a payload of data, or an action. The action construction may be wrapped into a semantic helper method which sends the payload to the dispatcher. For example, we may want to change the text of a to-do item in a to-do list application. We would create an action with a function signature like `updateText(todoId, newText)` in our `TodoActions` module. This method may be invoked from within our views' event handlers, so we can call it in response to a user action. This action method also adds the action type to the payload, so that when the payload is interpreted in the store, it can respond appropriately to a payload with a particular action type. In our example, this type might be named something like `TODO_UPDATE_TEXT`. Actions may also come from other places, such as the server. This happens, for example, during data initialization. It may also happen when the server returns an error code or when the server has updates to provide to the application. We'll talk more about server actions in a future article. In this post we're only concerned with the basics of the data flow. ### What About that Dispatcher? As mentioned earlier, the dispatcher is also able to manage dependencies between stores. This functionality is available through the `waitFor()` method within the Dispatcher class.  We did not need to use this method within the extremely simple [TodoMVC application](https://github.com/facebook/flux/tree/master/examples/flux-todomvc), but we have included it [in the example dispatcher](https://github.com/facebook/flux/blob/master/examples/flux-todomvc/js/dispatcher/Dispatcher.js#L110) as an example of what a dispatcher should be able to do in a larger, more complex application. Within the TodoStore's registered callback we could explicitly wait for any dependencies to first update before moving forward: ```javascript case 'TODO_CREATE': Dispatcher.waitFor([ PrependedTextStore.dispatcherIndex, YetAnotherStore.dispatcherIndex ], function() { TodoStore.create(PrependedTextStore.getText() + ' ' + action.text); TodoStore.emit('change'); }); break; ``` The arguments for `waitFor()` are an array of dispatcher registry indexes, and a final callback to invoke after the callbacks at the given indexes have completed.  Thus the store that is invoking `waitFor()` can depend on the state of another store to inform how it should update its own state. A problem arises if we create circular dependencies. If Store A waits for Store B, and B waits for A, then we'll have a very bad situation on our hands. We'll need a more robust dispatcher that flags these circular dependencies with console errors, and this is not easily accomplished with promises. Unfortunately, that's a bit beyond the scope of this documentation. In the future we hope to cover how to build a more robust dispatcher and how to initialize, update, and save the state of the application with persistent data, like a web service API.   This page has been moved to the Flux website. [View it there](http://facebook.github.io/flux/docs/overview.html).

--- id: flux-todo-list title: Flux TodoMVC Tutorial <del> prev: flux-overview.html </del> --- <del> To demonstrate the Flux architecture with some example code, let's take on the classic TodoMVC application. The entire application is available in the Flux GitHub repo within the [flux-todomvc](https://github.com/facebook/flux/tree/master/examples/flux-todomvc) example directory, but let's walk through the development of it a step at a time. To begin, we'll need some boilerplate and get up and running with a module system. Node's module system, based on CommonJS, will fit the bill very nicely and we can build off of [react-boilerplate](https://github.com/petehunt/react-boilerplate) to get up and running quickly. Assuming you have npm installed, simply clone the react-boilerplate code from GitHub, and navigate into the resulting directory in Terminal (or whatever CLI application you like). Next run the npm scripts to get up and running: `npm install`, then `npm run build`, and lastly `npm start` to continuously build using Browserify. The TodoMVC example has all this built into it as well, but if you're starting with react-boilerplate make sure you edit your package.json file to match the file structure and dependencies described in the TodoMVC example's [package.json](https://github.com/facebook/flux/tree/master/examples/flux-todomvc/package.json), or else your code won't match up with the explanations below. Source Code Structure --------------------- The resulting index.js file may be used as the entry point into our app, but we'll put most of our code in a 'js' directory. Let's let Browserify do its thing, and now we'll open a new tab in Terminal (or a GUI file browser) to look at the directory. It should look something like this: ``` myapp | + ... + js | + app.js + bundle.js // generated by Browserify whenever we make changes. + index.html + ... ``` Next we'll dive into the js directory, and layout our application's primary directory structure: ``` myapp | + ... + js | + actions + components // all React components, both views and controller-views + constants + dispatcher + stores + app.js + bundle.js + index.html + ... ``` Using the Dispatcher -------------------- We'll use the dispatcher from the [Flux GitHub repository](https://github.com/facebook/flux), but let's go over how to get it into our project, how it works and how we'll use it. The dispatcher's source code is written in [ECMAScript 6](https://github.com/lukehoban/es6features), the future version of JavaScript.  To use the future of JS in today's browser's we need to transpile it back to a version of JS that browsers can use.  We perform this build step, transpiling from ES6 into common JavaScript, using npm. You can get up and running with the dispatcher in a variety of ways, but perhaps the simplest is to use [Michael Jackson](https://twitter.com/mjackson)'s npm module version of the Flux project, called [react-dispatcher](https://www.npmjs.org/package/react-dispatcher): ``` npm install react-dispatcher ``` Afterward, you can require the dispatcher in your project's modules like so: ```javascript var Dispatcher = require('Flux').Dispatcher; ``` Alternatively, you can clone the Flux repo, run the Gulp-based build script with `npm install`, and then simply copy the dispatcher and invariant modules located inside flux/lib/ to the dispatcher directory for your project.  This the what we did in the [example code](https://github.com/facebook/flux/tree/master/examples/flux-todomvc/js/dispatcher). The two most important methods that the dispatcher exposes publically are register() and dispatch().  We'll use register() within our stores to register each store's callback. We'll use dispatch() within our action creators to trigger the invocation of the callbacks. ```javascript class Dispatcher { constructor() { this._callbacks = {}; this._isPending = {}; this._isHandled = {}; this._isDispatching = false; this._pendingPayload = null; } /** * Registers a callback to be invoked with every dispatched payload. * * @param {function} callback * @return {string} */ register(callback) { var id = _prefix + _lastID++; this._callbacks[id] = callback; return id; } // ... /** * Dispatches a payload to all registered callbacks. * * @param {object} payload */ dispatch(payload) { invariant( !this._isDispatching, 'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.' ); this._startDispatching(payload); try { for (var id in this._callbacks) { if (this._isPending[id]) { continue; } this._invokeCallback(id); } } finally { this._stopDispatching(); } } // ... _invokeCallback(id) { this._isPending[id] = true; this._callbacks[id](this._pendingPayload); this._isHandled[id] = true; } _startDispatching(payload) { for (var id in this._callbacks) { this._isPending[id] = false; this._isHandled[id] = false; } this._pendingPayload = payload; this._isDispatching = true; } _stopDispatching() { this._pendingPayload = null; this._isDispatching = false; } } ``` Now we are all set to create a dispatcher that is more specific to our app, which we'll call AppDispatcher. ```javascript var Dispatcher = require('./Dispatcher'); var merge = require('react/lib/merge'); var AppDispatcher = merge(Dispatcher.prototype, { /** * A bridge function between the views and the dispatcher, marking the action * as a view action.  Another variant here could be handleServerAction. * @param {object} action The data coming from the view. */ handleViewAction: function(action) { this.dispatch({ source: 'VIEW_ACTION', action: action }); } }); module.exports = AppDispatcher; ``` Now we've created an implementation that is a bit more specific to our needs, with a helper function we can use when we create actions. We might expand on this later to provide a separate helper for server updates, but for now this is all we need. You don't actually need to create an AppDispatcher in every application, but we wanted to show it here as an example.  The creation of the AppDispatcher allows us to extend the functionality of the Dispatcher.  In this application, for example, we have provided metadata about the source of the action outside of the action itself. Creating Stores ---------------- We can use Node's EventEmitter to get started with a store. We need EventEmitter to broadcast the 'change' event to our controller-views. So let's take a look at what that looks like. I've omitted some of the code for the sake of brevity, but for the full version see [TodoStore.js](https://github.com/Facebook/flux/blob/master/examples/flux-todomvc/js/stores/TodoStore.js) in the TodoMVC example code. ```javascript var AppDispatcher = require('../dispatcher/AppDispatcher'); var EventEmitter = require('events').EventEmitter; var TodoConstants = require('../constants/TodoConstants'); var merge = require('react/lib/merge'); var CHANGE_EVENT = 'change'; var _todos = {}; // collection of todo items /** * Create a TODO item. * @param {string} text The content of the TODO */ function create(text) { // Using the current timestamp in place of a real id. var id = Date.now(); _todos[id] = { id: id, complete: false, text: text }; } /** * Delete a TODO item. * @param {string} id */ function destroy(id) { delete _todos[id]; } var TodoStore = merge(EventEmitter.prototype, { /** * Get the entire collection of TODOs. * @return {object} */ getAll: function() { return _todos; }, emitChange: function() { this.emit(CHANGE_EVENT); }, /** * @param {function} callback */ addChangeListener: function(callback) { this.on(CHANGE_EVENT, callback); }, /** * @param {function} callback */ removeChangeListener: function(callback) { this.removeListener(CHANGE_EVENT, callback); }, dispatcherIndex: AppDispatcher.register(function(payload) { var action = payload.action; var text; switch(action.actionType) { case TodoConstants.TODO_CREATE: text = action.text.trim(); if (text !== '') { create(text); TodoStore.emitChange(); } break; case TodoConstants.TODO_DESTROY: destroy(action.id); TodoStore.emitChange(); break; // add more cases for other actionTypes, like TODO_UPDATE, etc. } return true; // No errors. Needed by promise in Dispatcher. }) }); module.exports = TodoStore; ``` There are a few important things to note in the above code. To start, we are maintaining a private data structure called _todos. This object contains all the individual to-do items. Because this variable lives outside the class, but within the closure of the module, it remains private — it cannot be directly changed from the outside. This helps us preserve a distinct input/output interface for the flow of data by making it impossible to update the store without using an action. Another important part is the registration of the store's callback with the dispatcher. We pass in our payload handling callback to the dispatcher and preserve the index that this store has in the dispatcher's registry. The callback function currently only handles two actionTypes, but later we can add as many as we need. Listening to Changes with a Controller-View ------------------------------------------- We need a React component near the top of our component hierarchy to listen for changes in the store. In a larger app, we would have more of these listening components, perhaps one for every section of the page. In Facebook's Ads Creation Tool, we have many of these controller-like views, each governing a specific section of the UI. In the Lookback Video Editor, we only had two: one for the animated preview and one for the image selection interface. Here's one for our TodoMVC example. Again, this is slightly abbreviated, but for the full code you can take a look at the TodoMVC example's [TodoApp.react.js](https://github.com/facebook/flux/blob/master/examples/flux-todomvc/js/components/TodoApp.react.js) ```javascript /** @jsx React.DOM */ var Footer = require('./Footer.react'); var Header = require('./Header.react'); var MainSection = require('./MainSection.react'); var React = require('react'); var TodoStore = require('../stores/TodoStore'); function getTodoState() { return { allTodos: TodoStore.getAll() }; } var TodoApp = React.createClass({ getInitialState: function() { return getTodoState(); }, componentDidMount: function() { TodoStore.addChangeListener(this._onChange); }, componentWillUnmount: function() { TodoStore.removeChangeListener(this._onChange); }, /** * @return {object} */ render: function() { return ( <div> <Header /> <MainSection allTodos={this.state.allTodos} areAllComplete={this.state.areAllComplete} /> <Footer allTodos={this.state.allTodos} /> </div> ); }, _onChange: function() { this.setState(getTodoState()); } }); module.exports = TodoApp; ``` Now we're in our familiar React territory, utilizing React's lifecycle methods. We set up the initial state of this controller-view in getInitialState(), register an event listener in componentDidMount(), and then clean up after ourselves within componentWillUnmount(). We render a containing div and pass down the collection of states we got from the TodoStore. The Header component contains the primary text input for the application, but it does not need to know the state of the store. The MainSection and Footer do need this data, so we pass it down to them. More Views ---------- At a high level, the React component hierarchy of the app looks like this: ```javascript <TodoApp> <Header> <TodoTextInput /> <MainSection> <ul> <TodoItem /> </ul> </MainSection> </Header> </TodoApp> ``` If a TodoItem is in edit mode, it will also render a TodoTextInput as a child. Let's take a look at how some of these components display the data they receive as props, and how they communicate through actions with the dispatcher. The MainSection needs to iterate over the collection of to-do items it received from TodoApp to create the list of TodoItems. In the component's render() method, we can do that iteration like so: ```javascript var allTodos = this.props.allTodos; for (var key in allTodos) { todos.push(<TodoItem key={key} todo={allTodos[key]} />); } return ( <section id="main"> <ul id="todo-list">{todos}</ul> </section> ); ``` Now each TodoItem can display its own text, and perform actions utilizing its own ID. Explaining all the different actions that a TodoItem can invoke in the TodoMVC example goes beyond the scope of this article, but let's just take a look at the action that deletes one of the to-do items. Here is an abbreviated version of the TodoItem: ```javascript /** @jsx React.DOM */ var React = require('react'); var TodoActions = require('../actions/TodoActions'); var TodoTextInput = require('./TodoTextInput.react'); var TodoItem = React.createClass({ propTypes: { todo: React.PropTypes.object.isRequired }, render: function() { var todo = this.props.todo; return ( <li key={todo.id}> <label> {todo.text} </label> <button className="destroy" onClick={this._onDestroyClick} /> </li> ); }, _onDestroyClick: function() { TodoActions.destroy(this.props.todo.id); } }); module.exports = TodoItem; ``` With a destroy action available in our library of TodoActions, and a store ready to handle it, connecting the user's interaction with application state changes could not be simpler. We just wrap our onClick handler around the destroy action, provide it with the id, and we're done. Now the user can click the destroy button and kick off the Flux cycle to update the rest of the application. Text input, on the other hand, is just a bit more complicated because we need to hang on to the state of the text input within the React component itself. Let's take a look at how TodoTextInput works. As you'll see below, with every change to the input, React expects us to update the state of the component. So when we are finally ready to save the text inside the input, we will put the value held in the component's state in the action's payload. This is UI state, rather than application state, and keeping that distinction in mind is a good guide for where state should live. All application state should live in the store, while components occasionally hold on to UI state. Ideally, React components preserve as little state as possible. Because TodoTextInput is being used in multiple places within our application, with different behaviors, we'll need to pass the onSave method in as a prop from the component's parent. This allows onSave to invoke different action creator methods depending on where it is used. ```javascript /** @jsx React.DOM */ var React = require('react'); var ReactPropTypes = React.PropTypes; var ENTER_KEY_CODE = 13; var TodoTextInput = React.createClass({ propTypes: { className: ReactPropTypes.string, id: ReactPropTypes.string, placeholder: ReactPropTypes.string, onSave: ReactPropTypes.func.isRequired, value: ReactPropTypes.string }, getInitialState: function() { return { value: this.props.value || '' }; }, /** * @return {object} */ render: function() /*object*/ { return ( <input className={this.props.className} id={this.props.id} placeholder={this.props.placeholder} onBlur={this._save} onChange={this._onChange} onKeyDown={this._onKeyDown} value={this.state.value} autoFocus={true} /> ); }, /** * Invokes the callback passed in as onSave, allowing this component to be * used in different ways. */ _save: function() { this.props.onSave(this.state.value); this.setState({ value: '' }); }, /** * @param {object} event */ _onChange: function(/*object*/ event) { this.setState({ value: event.target.value }); }, /** * @param {object} event */ _onKeyDown: function(event) { if (event.keyCode === ENTER_KEY_CODE) { this._save(); } } }); module.exports = TodoTextInput; ``` The Header passes in the onSave method as a prop to allow the TodoTextInput to create new to-do items: ```javascript /** @jsx React.DOM */ var React = require('react'); var TodoActions = require('../actions/TodoActions'); var TodoTextInput = require('./TodoTextInput.react'); var Header = React.createClass({ /** * @return {object} */ render: function() { return ( <header id="header"> <h1>todos</h1> <TodoTextInput id="new-todo" placeholder="What needs to be done?" onSave={this._onSave} /> </header> ); }, /** * Event handler called within TodoTextInput. * Defining this here allows TodoTextInput to be used in multiple places * in different ways. * @param {string} text */ _onSave: function(text) { TodoActions.create(text); } }); module.exports = Header; ``` In a different context, such as in editing mode for an existing to-do item, we might pass an onSave callback that invokes `TodoActions.update(text)` instead. Creating Actions with Semantic Methods -------------------------------------- Here is the basic code for the two action creator methods we used above in our views: ```javascript /** * TodoActions */ var AppDispatcher = require('../dispatcher/AppDispatcher'); var TodoConstants = require('../constants/TodoConstants'); var TodoActions = { /** * @param {string} text */ create: function(text) { AppDispatcher.handleViewAction({ actionType: TodoConstants.TODO_CREATE, text: text }); }, /** * @param {string} id */ destroy: function(id) { AppDispatcher.handleViewAction({ actionType: TodoConstants.TODO_DESTROY, id: id }); }, }; module.exports = TodoActions; ``` As you can see, we really would not need to have the helpers AppDispatcher.handleViewAction() or TodoActions.create(). We could, in theory, call AppDispatcher.dispatch() directly and provide a payload. But as our application grows, having these helpers keeps the code clean and semantic. It's just a lot cleaner to write TodoActions.destroy(id) instead of writing a whole lot of things that our TodoItem shouldn't have to know about. The payload produced by the TodoActions.create() will look like: ```javascript { source: 'VIEW_ACTION', action: { type: 'TODO_CREATE', text: 'Write blog post about Flux' } } ``` This payload is provided to the TodoStore through its registered callback. The TodoStore then broadcasts the 'change' event, and the MainSection responds by fetching the new collection of to-do items from the TodoStore and changing its state. This change in state causes the TodoApp component to call its own render() method, and the render() method of all of its descendents. Start Me Up ----------- The bootstrap file of our application is app.js. It simply takes the TodoApp component and renders it in the root element of the application. ```javascript /** @jsx React.DOM */ var React = require('react'); var TodoApp = require('./components/TodoApp.react'); React.renderComponent( <TodoApp />, document.getElementById('todoapp') ); ``` Dependency Management in the Dispatcher ---------------------------------------------- As our application grows beyond this simple application to contain multiple stores, we'll need a way to be able to manage dependencies between them. That is, Store A might need to derive data based on Store B's data, so Store A would need Store B to update itself first.  This functionality is available with the Dispatcher's waitFor() method. We would call waitFor() within the store's registered callback like so: ```javascript Dispatcher.waitFor([StoreB.dispatcherIndex, StoreC.dispatcherIndex]); // now do things, knowing that both StoreB and StoreC have updated ``` In the source code, you can see that we are interupting the synchronous iteration over the callbacks and starting a new iteration of callbacks based on the array of dispatcherIndexes passed into waitFor(). ```javascript /** * Waits for the callbacks specified to be invoked before continuing execution * of the current callback. This method should only be used by a callback in * response to a dispatched payload. * * @param {array<string>} ids */ waitFor(ids) { invariant( this._isDispatching, 'Dispatcher.waitFor(...): Must be invoked while dispatching.' ); for (var ii = 0; ii < ids.length; ii++) { var id = ids[ii]; if (this._isPending[id]) { invariant( this._isHandled[id], 'Dispatcher.waitFor(...): Circular dependency detected while ' + 'waiting for `%s`.', id ); continue; } invariant( this._callbacks[id], 'Dispatcher.waitFor(...): `%s` does not map to a registered callback.', id ); this._invokeCallback(id); } } ``` Now within the store's callback we can explicitly wait for any dependencies to first update before moving forward.  However, if Store A waits for Store B, and B waits for A, then a circular dependency will occur. To help prevent this situation, the dispatcher will throw an error in the browser console if we accidentally have two stores that are waiting for each other. The Future of Flux ------------------ A lot of people ask if Facebook will release Flux as an open source framework. Really, Flux is just an architecture, not a framework.  But perhaps a Flux boilerplate project might make sense, if there is enough interest. Please let us know if you'd like to see us do this. Thanks for taking the time to read about how we build client-side applications at Facebook. We hope Flux proves as useful to you as it has to us. </del> <ins> This page has been moved to the Flux website. [View it there](http://facebook.github.io/flux/docs/todo-list.html). </ins>


Question:
In 0.11, the code assigned implicit keys to both children. In 0.12, it gives the error and renders only "foo", because the key is cast to a string in ReactElement before it gets checked against null in traverseAllChildren: I guess it's okay if this is intentional but it broke a part of KA in the upgrade. (cc
hm. Yea, this was intentional to ensure more stable types through out the system. I don't think null should be treated as a valid "non-value" to align it with defaultProps, default arguments and default values in destructuring. The intention of "null" is to symbolize a missing object. However, this can be of any type. It's weird that is coerced into . It should be left as . For refs, we expect them to become objects so it is valid to have there to represent a missing value. We have a two options: 1) Allow any value to be coerced to strings. 2) Throw on non-string values. 3) Don't coerce to string and start using maps as keys. E.g. Dates would become by reference instead of by value. would be treated as a key and would still be duplicate.
Maybe we can support meaning no key for a 0.12 with a warning, then drop support in 0.13? Just trying to avoid breaking things (that are impossible to grep for) without a warning. (I have no idea if we have other places in our code that do this by accident…)
They don't in prod though, right? I thought we had a fallback for duplicate values that would be essentially the same?
No, that code previously outputted and outputs just with 0.12. We ignore all children after the first with a given key.
oh. fine, warning for one version and then swap behavior. Want to send a PR?
Will do.

if (config != null) { ref = config.ref === undefined ? null : config.ref; <del> key = config.key === undefined ? null : '' + config.key; </del> <ins> if (__DEV__) { warning( config.key !== null, 'createElement(...): Encountered component with a `key` of null. In ' + 'a future version, this will be treated as equivalent to the string ' + ''null'; instead, provide an explicit key or use undefined.' ); } // TODO: Change this back to `config.key === undefined` key = config.key == null ? null : '' + config.key; </ins> // Remaining properties are added to a new props object for (propName in config) { if (config.hasOwnProperty(propName) &&

expect(element.props).toEqual({foo:'56'}); }); <ins> it('treats a null key as omitted but warns', function() { spyOn(console, 'warn'); var element = React.createFactory(ComponentFactory)({ key: null, foo: '56' }); expect(element.type).toBe(ComponentClass); expect(element.key).toBe(null);  // as opposed to string 'null' expect(element.ref).toBe(null); expect(element.props).toEqual({foo:'56'}); expect(console.warn.argsForCall.length).toBe(1); expect(console.warn.argsForCall[0][0]).toContain( 'will be treated as equivalent to the string 'null'' ); }); </ins> it('preserves the context on the element', function() { var Component = React.createFactory(ComponentFactory); var element;


Question:
We need a way to test the output of a single level React component without resolving it all the way down to the bottom layer (whatever that is). I'm thinking something like this: Basically, this fix needs to go through the entire life-cycle of ReactCompositeComponent. It just needs to bail out whenever it would've continued rendering.
Reopened so that we can track the remaining features (refs etc.)
Weird, I thought GitHub only closed issues if you used language like "fixes #NNNN", not if you simply mentioned the issue at all. Sorry about that.
The PR text included "WIP to "
Is the rest (refs support) blocked by or can more work be done now?
Any reason this doesn't support other than that it's not implemented yet? I was hoping to do something like
that's supposed to work. Can you post a minimal repro?
How do you do this?  does not return an instance.
It works if I use so I think could just return that from . (I also have to shim because React expects it to be defined for some reason.)
Finding this quite useful. But it has been a bit inconvenient to have among the children when an element is conditionally rendered.
The idea was to make the helpers ignore null which could help with that. Perhaps we could have return an iterable which traverses nested arrays and ignores null.
Really? Allowing nulls was a change intentionally introduced a long time ago. In I have an implementation of toArray.
Allowing empty children (null, undefined, boolean) was a controversial topic, where we eventually landed on null/boolean/undefined being passed through. That way you could explicitly treat an empty slot as something special. This landed very early on before we really started seeing pattern developing. However, IMO, we've seen that this leads to inconsistent implementations where null slots will break and is not possible to use. It is unclear whether a set of children allows nullable slots, and if they do, it is unclear what that means. For example, in a grid layout component, does an empty slot mean that there should be an empty column in the grid, or that it should be skipped? Therefore, a lot of our components end up with explicit null checks. Meaning boilerplate, and inconsistent behavior when they're forgotten. Therefore, I think the default should be to filter out nulls which is consistent with the behavior of the built-ins components. It is still possible to get access to the raw data if you have a different type of children in mind where empty slots is meaningful.
How should this work with the TestUtils functions. For example, this fails: I can't see any other info on mentioned at the start of this issue, is this what I'm missing? My end goal is simply to test that if I pass in 10 articles then 10 components get rendered. Any help would be awesome.
Hi David, the and functions are meant to be used with the output of , not shallow rendering. React doesn't currently provide a helper that will traverse trees for you. Your options for now are to describe the structure of the tree explicitly as in lines 4-5 of your example, or write your own helper module to find descendants you care about. hasn't been implemented yet. Refer to the for what's actually in React.
Cool, thanks for the reply I've returned to just using since the components I'm testing (and their children) don't have state/stores so don't really need mocking out anyway. One last (maybe stupid) question, what does mean?
So, I am trying to use Shallow Rendering and have it mostly only thing left I can’t figure out is the recommended way to mock events and how to get with events to pass. I've attempted to use the method directly from the in the test (). This seems dirty…is there a way to just say or something? I could post this on Stack Overflow, but I have had very little luck finding good information about Shallow Rendering online. If anyone has experience with shallow rendering and can give me some help you will be my hero... Source code: ! !
If I have an issue with shallow rendering, should I create a new issue, or post it here?
New issue please.
you might find that helps in providing higher-level assertions for the sort of thing you're doing there. In that particular case, I would avoid asserting on the event handler of the anchor in that test - but a different test would want to call to test the handler.
Super late reply, but "scry" is a fancy word for "find". I'm not sure why we don't just use "find". Maybe to avoid confusion between the plural and singular forms, whose names would otherwise differ only by one "s".
scry is because of legacy internal FB APIs. No reason.
Like I'm keenly on the lookout for a way to correctly unit test event handling in React code. Is there any documentation that anyone could point me to? I've looked at but it didn't seem to have something that scratches my particular itch. Here's my scenario (cut down): Where Problem looks like this: I'd like to be able to assert that is wired up for my component but I'm at a loss as to how to do that....
What you actually want is to assert that clicking interacts with the router. Pass in a fake context with a router mock (try Simon) then call Apologies for the brevity, on a phone.
Hi Thanks for responding. I'm not too clear on how to mock successfully when it comes to context. Digging through the source of I came up with this: However this dies a death with: Which makes me think I'm getting the context mocking wrong. Do you know how you successfully mock context with ? I'm using Jasmine (as you probably guessed!) I have a feeling I'm close...
Are you using React 0.13? You're probably hitting the difference between parent & owner context. Skin deep has a wrapper that helps with this - there's a context example the test suite, but the short answer is to wrap your render in another function call and let skin deep set up the context. This problem should go away in 0.14
I am using React 0.13, yes. If I port to 0.14 this issue should resolve? I might give that a crack if that's the case (it is in RC after all)
Problems with the upgrade. I have raised . Will have to return to this later I think.
I have written and as companion tools when testing with shallow rendering. It gives you the ability to diff on JSX strings rendered instead of React element objects.
Hi, I was wondering what was the state of: simulating events when using shallow rendering using refs when using shallow rendering How can we help make this happen if that's still planned?
This issue is pretty stale so I’ll close it. If there are specific features you miss in the shallow renderer please create new issues with proposals on how they should work. Note that we a new that is much more feature-complete.

/** * @private */ <ins> _renderValidatedComponentWithoutOwnerOrContext: function() { var inst = this._instance; var renderedComponent = inst.render(); if (__DEV__) { // We allow auto-mocks to proceed as if they're returning null. if (typeof renderedComponent === 'undefined' && inst.render._isMockFunction) { // This is probably bad practice. Consider warning here and // deprecating this convenience. renderedComponent = null; } } return renderedComponent; }, /** * @private */ </ins> _renderValidatedComponent: ReactPerf.measure( 'ReactCompositeComponent', '_renderValidatedComponent',

ReactCurrentOwner.current = this; var inst = this._instance; try { <del> renderedComponent = inst.render(); if (__DEV__) { // We allow auto-mocks to proceed as if they're returning null. if (typeof renderedComponent === 'undefined' && inst.render._isMockFunction) { // This is probably bad practice. Consider warning here and // deprecating this convenience. renderedComponent = null; } } </del> <ins> renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext(); </ins> } finally { ReactContext.current = previousContext; ReactCurrentOwner.current = null;

}); <ins> var ShallowMixin = assign({}, ReactCompositeComponentMixin, { /** * Initializes the component, renders markup, and registers event listeners. * * @param {string} rootID DOM ID of the root node. * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @param {number} mountDepth number of components in the owner hierarchy * @return {ReactElement} Shallow rendering of the component. * @final * @internal */ mountComponent: function(rootID, transaction, mountDepth) { ReactComponent.Mixin.mountComponent.call( this, rootID, transaction, mountDepth ); var inst = this._instance; // Store a reference from the instance back to the internal representation ReactInstanceMap.set(inst, this); this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING; // No context for shallow-mounted components. inst.props = this._processProps(this._currentElement.props); var initialState = inst.getInitialState ? inst.getInitialState() : null; if (__DEV__) { // We allow auto-mocks to proceed as if they're returning null. if (typeof initialState === 'undefined' && inst.getInitialState._isMockFunction) { // This is probably bad practice. Consider warning here and // deprecating this convenience. initialState = null; } } invariant( typeof initialState === 'object' && !Array.isArray(initialState), '%s.getInitialState(): must return an object or null', inst.constructor.displayName || 'ReactCompositeComponent' ); inst.state = initialState; this._pendingState = null; this._pendingForceUpdate = false; if (inst.componentWillMount) { inst.componentWillMount(); // When mounting, calls to `setState` by `componentWillMount` will set // `this._pendingState` without triggering a re-render. if (this._pendingState) { inst.state = this._pendingState; this._pendingState = null; } } // No recursive call to instantiateReactComponent for shallow rendering. this._renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext(); // Done with mounting, `setState` will now trigger UI changes. this._compositeLifeCycleState = null; // No call to this._renderedComponent.mountComponent for shallow // rendering. if (inst.componentDidMount) { transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); } return this._renderedComponent; }, /** * Call the component's `render` method and update the DOM accordingly. * * @param {ReactReconcileTransaction} transaction * @internal */ _updateRenderedComponent: function(transaction) { var prevComponentInstance = this._renderedComponent; var prevRenderedElement = prevComponentInstance._currentElement; // Use the without-owner-or-context variant of _rVC below: var nextRenderedElement = this._renderValidatedComponentWithoutOwnerOrContext(); if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { prevComponentInstance.receiveComponent( nextRenderedElement, transaction ); } else { // These two IDs are actually the same! But nothing should rely on that. var thisID = this._rootNodeID; var prevComponentID = prevComponentInstance._rootNodeID; // Don't unmount previous instance since it was never mounted, due to // shallow render. //prevComponentInstance.unmountComponent(); this._renderedComponent = nextRenderedElement; // ^ no instantiateReactComponent // // no recursive mountComponent return nextRenderedElement; } } }); </ins> var ReactCompositeComponent = { LifeCycle: CompositeLifeCycle, <del> Mixin: ReactCompositeComponentMixin </del> <ins> Mixin: ReactCompositeComponentMixin, ShallowMixin: ShallowMixin </ins> };

// an external backing store so that we can freeze the whole object. // This can be replaced with a WeakMap once they are implemented in // commonly used development environments. <del> this._store = { validated: false, props: props }; </del> <ins> this._store = { props: props }; // To make comparing ReactElements easier for testing purposes, we make // the validation flag non-enumerable (where possible, which should // include every environment we run tests in), so the test framework // ignores it. try { Object.defineProperty(this._store, 'validated', { configurable: false, enumerable: false, writable: true }); } catch (x) { } this._store.validated = false; </ins> // We're not allowed to set props directly on the object so we early // return and rely on the prototype membrane to forward to the backing

var React = require('React'); var ReactElement = require('ReactElement'); var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter'); <ins> var ReactCompositeComponent = require('ReactCompositeComponent'); var ReactInstanceHandles = require('ReactInstanceHandles'); </ins> var ReactInstanceMap = require('ReactInstanceMap'); var ReactMount = require('ReactMount'); var ReactUpdates = require('ReactUpdates'); var SyntheticEvent = require('SyntheticEvent'); var assign = require('Object.assign'); <ins> var instantiateReactComponent = require('instantiateReactComponent'); </ins> var topLevelTypes = EventConstants.topLevelTypes;

}; }, <ins> createRenderer: function() { return new ReactShallowRenderer(); }, </ins> Simulate: null, SimulateNative: {} }; /** <ins> * @class ReactShallowRenderer */ var ReactShallowRenderer = function() { this._instance = null; }; ReactShallowRenderer.prototype.getRenderOutput = function() { return (this._instance && this._instance._renderedComponent) || null; }; var ShallowComponentWrapper = function(inst) { this._instance = inst; } assign( ShallowComponentWrapper.prototype, ReactCompositeComponent.ShallowMixin ); ReactShallowRenderer.prototype.render = function(element) { var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); this._render(element, transaction); ReactUpdates.ReactReconcileTransaction.release(transaction); }; ReactShallowRenderer.prototype._render = function(element, transaction) { if (!this._instance) { var rootID = ReactInstanceHandles.createReactRootID(); var instance = new ShallowComponentWrapper(new element.type(element.props)); instance.construct(element); instance.mountComponent(rootID, transaction, 0); this._instance = instance; } else { this._instance.receiveComponent(element, transaction); } }; /** </ins> * Exports: * * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)`

 /** * Copyright 2013-2014, 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"; var React; var ReactTestUtils; var mocks; var warn; describe('ReactTestUtils', function() { beforeEach(function() { mocks = require('mocks'); React = require('React'); ReactTestUtils = require('ReactTestUtils'); warn = console.warn; console.warn = mocks.getMockFunction(); }); afterEach(function() { console.warn = warn; }); it('should have shallow rendering', function() { var SomeComponent = React.createClass({ render: function() { return (

 ); } }); var shallowRenderer = ReactTestUtils.createRenderer(); shallowRenderer.render(<SomeComponent />); var result = shallowRenderer.getRenderOutput(); expect(result.type).toBe('div'); expect(result.props.children).toEqual([ ,  ]); }); it('lets you update shallowly rendered components', function() { var SomeComponent = React.createClass({ getInitialState: function() { return {clicked: false}; }, onClick: function() { this.setState({clicked: true}); }, render: function() { var className = this.state.clicked ? 'was-clicked' : ''; if (this.props.aNew === 'prop') { return (  Test link  ); } else { return (

 ); } } }); var shallowRenderer = ReactTestUtils.createRenderer(); shallowRenderer.render(<SomeComponent />); var result = shallowRenderer.getRenderOutput(); expect(result.type).toBe('div'); expect(result.props.children).toEqual([ ,  ]); shallowRenderer.render(<SomeComponent aNew="prop" />); var updatedResult = shallowRenderer.getRenderOutput(); expect(updatedResult.type).toBe('a'); var mockEvent = {}; updatedResult.props.onClick(mockEvent); var updatedResultCausedByClick = shallowRenderer.getRenderOutput(); expect(updatedResultCausedByClick.type).toBe('a'); expect(updatedResultCausedByClick.props.className).toBe('was-clicked'); }); });


Question:
People lose hours of work debugging a simple issue: two versions of React being loaded at the same time. Because there is no warning right away when this happens, they usually discover the problem through invariant violations. Some of them are descriptive (e.g. ) and I think I even saw warning that said something like "check if two copies of React are loaded", but some are really cryptic: . Is there a reason why we don't want to warn right away when two copies of React are loaded?
There's probably no good way to find out if two copies of React are loaded (CommonJS modules are the antithesis of sharing a global scope, they're literally two duplicate but separate modules). But I would expect React to be clever enough to figure out that, say, a component is a React component even if it's not from the same copy of React.
I think it's lesser evil to put some flag on , like , than to spend any more time on this.
Should be preferable to just extend (or w/e) with simple duck-typing that warns if it looks like a ReactElement but isn't... or something like that. It's free and doesn't interfere with intentionally running multiple React instances.
I think that in the future, this will actually just work. In the meantime we can warn here:
Would it catch all of the issues listed above though? Usually the problem comes up when some component or helper library loads its own version. Will we get to in this case? Besides, does React truly support independent Reacts on page right now? Do they not interfere in any way at all if they aren't mixed (e.g. browser event handling)?
(To clarify, I was referring to comment)
I might be mistaken, but ignoring weird hacks then the only issue with multiple instances of React are when ReactElements from different instances gets mixed up. Depending on which API you feed them to, you're going to see lots of different errors though. So yeah... I think that should take care of all, or most at the very least. As long as you never stop event propagation or mount them inside each other it should be OK I think (but still not great though). Good point.
Just a confirmation from someone who just flushed 3 hours of debugging time down the toilet that, yes, this issue is hard to debug, please make at least a warning. In my case I was having a weird exception (TypeError: Cannot read property 'firstChild' of undefined) caused by the fact that a component created with a different (uninitialised) copy of React was carrying a _owner = null, thereby breaking findComponentRoot().
We should already be warning in the case that an element from one copy of React is passed to in another: I guess the cases here are when nesting elements from different versions inside each other?
Yes. At least it was in my case. Nested elements created from different React versions.
Just my 2cents: I had the same issue today and my problem was using browserify 8.1.3 instead of 8.1.1 Hope it helps
The other issue with this is you can't reliably use the dependency injection mechanism, e.g. to change the batching strategy, while using components from multiple modules where each has it's own instance of React as a dependency. Even if they are the same version of React.
+1 ; thanks gaearon
said: "The other issue with this is you can't reliably use the dependency injection mechanism, e.g. to change the batching strategy, while using components from multiple modules where each has it's own instance of React as a dependency. Even if they are the same version of React." This.
The main workaround many modular React components are using is to specify React as a -- the parent module must provide React to prevent multiple copies. This is problematic because are on track to because they introduce .
I've seen this a lot as well, and had lots of requests to switch React to a (+) in my packages which I'm currently resisting for reasons mentioned. The most common frustration I've seen is when npm subtly installs two versions of React, and Browserify (correctly) includes both in the build. It can happen unexpectedly w/ package updates and breakage ensues. A warning from React that "hey, there is more than one of me on the page" seems like the most elegant way to warn developers early and direct them to an explanation of what's gone wrong / how to fix it. It's a side-effect of npm's dependency rules and node's behaviour that I end up with two Reacts when I just want one. Looks like things will get better with (see npm/npm) but in the meantime I agree with about adding a "lesser evil" hack: ... there's a good argument to be made that this isn't React's problem to solve, but since it's a common problem and React can solve it, I think it would be great if it did.
A solution I found with was to alias all calls like so (example shown with grunt): so it isn't impossible to fix, but I'd make the argument that since this is such a common issue it needs to be highlighted more clearly in the React docs.
when using browserify it can happen just when requiring two different versions of React because of the way it handles deduplication. Requires with the same path and code between the two versions can end up getting de-duped. Modules where the code/require path was changed between versions get deduplicated and others don't. So I encountered this: (from React v1) is evaluated and it mixes in ReactBrowserComponentMixin as part of its spec .Class.injectMixin(ReactBrowserComponentMixin) is evaluated and it adds ReactBrowserComponentMixin to all classes subsequently created by ReactClass.createClass (shared between React v1 and v2 because it didn't change between the two versions of React) (from React v2) is evaluated and it tries to mix in ReactBrowserComponentMixin twice, once from ReactDOMSelect's own spec and once from the global injected mixin list. As long as modules can be stateful, this approach to deduplication seems horrifically unsafe. I'll file an issue with Browserify itself, I haven't yet verified if Webpack would have the same issue. Either way - I think it would make sense to handle it specifically in React given how it can trip newcomers up.
Reverting for now (in ) as we sort out some problems.
THANK YOU for this discussion. I was battling with an Invariant Violation bug for half the day yesterday and then came across this ticket this morning. My setup was using a browserify-shimmed version of React and react-router loaded from CDN. After reading this discussion I just opted to use the npm versions of these libs and the error went away. This is my first React project so debugging this problem was a pretty big headache. Thanks again for this discussion as it lead me to figure out the problem and move forward.
Leaving details of my case for future searchers: I got the error "Invariant Violation: Could not find the drag and drop manager in the context of Card. Make sure to wrap the top-level component of your app with configureDragDropContext" Also turned out I had two React versions loaded. The problem was Webpack. I was using "npm link <folder" for one of my packages, which also depends on React. Seems webpack has problems handling symbolic links, or it's my fault configuring it improperly. Anyway, the problem was fixed by installing the package into my local node_modules directory.
Thanks for this, I'm gonna add it to the relevant explanation gist for React DnD.
Would like to have this too. Haven't figured out a way to get GitHub cc'd (rather than bcc'd) without explicitly participating, sorry for the noise.
There's a button :)
I think that still doesn't CC you but only BCC, sadly. Moreover, I'm watching the repo already, but I have a different inbox for when GitHub CCs me.
Fyi: Ongoing PR
Fixed by , hopefully.
If it helps the next person googling, is yet another sign of this problem.
and counting... I've got this one: I'm looking everywhere for the sneaky react twin, but no luck. doesn't show any duplicates The other possibilities I've read about are double-loading the react script, webpack double-bundling, or react/addons causing trouble, so those are what I'm working on now. Insidious.
As you've hopefully set up correctly, then simply remove and reinstall everything, that usually fixes it unless there's some incorrectly configured module.
I tried to git clone the repo and reinstall, but that wasn't the issue. Eventually I noticed that the error was only happening after the first navigation (similar to this ) and started taking apart my navigation menu. Turns out that for some reason putting a from react-router inside a from react-boostrap was causing react to go nuts. I posted my findings on .
I think it also might have had something to do with my not using the generated from react-router as the root of my component hierarchy. I was wrapping it in a higher level-component that accepts my flux instance and passes it on as context. Isolating the issue into gave me the following error:
The nested links thing is due to invalid HTML and we have a new warning for that in 0.14.
By the way I got that new warning a few days ago and it's beautiful, great work. :+1:
I'm getting this error: when using npm link to require a module I'm working on. I can't be 100% sure that it's caused by having multiple versions of React, but the error does go away when I just paste the npm module directly into my app instead of using it via npm link. I don't get this error when using my npm module the normal way (react is a dev dependency so I don't think it gets installed in node modules). Has anyone else run into this issue and come up with a fix? Thanks!
I got this error while running 0.14-rc1 and 0.14-beta3 together
Please do not report random problems in this issue. File new issues.
Seriously. This has taken me 3 days to figure out that my random error about unmounting the _mouseMoveTracker twice in fixed-data-table is caused by two reacts... This is not good that this bug seemingly can't be fixed? Why can React not just put the version number on the window object and never add itself again if it's there already? This is better than the hours and hours wasted by many people with this!
I thought we fixed this in 0.14 (); is it not displaying a warning?
Yep, I just upgraded to 0.14.2 everywhere (including inside the module) and somehow deleting react from nodemodules/react-datatable/nodemodules/ fixed my bug! (see here ). Maybe there is something wrong with my webpack config? It's weird that this fixed it. Is this having two of the identical version included a subtle variant on this bug?
Part of the problem is react-datatable having as a non-peer dependency (cc which can cause NPM to fetch a separate react installation for just that module.
Okay - thanks - I'll try adding this as a peer dep, however when I want to run the build for my module if developing the datatable from within my main project, what is the best way to accomplish this without issues?
you might try upgrading to , then . has improvements in how it handles dependencies and is better about avoiding multiple instances of a given package, since it installs with a flat structure instead of nesting dependencies within packages. This, along with moving from to in a library I am writing, solved my similar problems.
Another 4 hours lost. My webpack config now is:
Can you say what symptom you experienced? Also, if you are using the prebuilt I would recommend using the prebuilt react- as well and using in your webpack config since the secret property is unstable and will change in the next version (hence its name).
yes, the problem was in prebuild version of React. The second instance of React came from require('react'). It did work somehow until React 0.14 migration. And even more: It work after partial code removal! This lead me to wrong way of long debugging. I agree, this is my fault. But I still expect something like: every time, instead of rare warning: after which I spent hours to find out whats wrong with my refs... It seems like it is very common problem, and it is have to be more detailed and have better documentation.
same issue with webpack and loading manually.
Is it still an issue to load more than one version of React on a page, even if those instances are managing totally separate DOM trees and aren't being explicitly instantiated as globals? Like if, say, I had a package with and as dependencies, and they both depended on different versions of React, with npm as the dependency manager, could they be used together on one page?
No, that should work now if both are on a recent version of React.
Could you please point me out what would be the behavior of React if , let say , we want to introduce a widget including React in a host page that has an older version of it and the possible workaround to make it work? Thanks
Old versions of React are probably only tripped up by data-reactid IDs in the DOM that it didn't generate. If you're doing only client-side rendering with your widget, it should only have a data-reactroot attribute and no data-reactid so there shouldn't be any conflict.
Just ran into problems again today when I accidentally had 16.4.2 and 16.5.0 installed in a project, no warning from React. To make matters worse, the duplicate versions were caused by a bug in that ...
Was there any resolution as to whether or not this is possible and/or a good idea? It seems like it'd provide developers with useful information.
Project A uses React 16 wherein Project B uses React 15, Lets say Project A is package got used in Project B - can that work?
Would Preact and React have the same issue described here? I’m asking because I’m using single-spa for a platform play at a large company of distributed teams.
It sounds to me like there are two separate issues here: you have two different copies of the library loaded and in use anywhere on a page in separate components that don't interact with each other? you have components from two different bundles, each with their own copy of the library, interact with each other (eg. the function from one library receiving an element created with from the other library) I don't know about the status with modern versions of React. In the case of Preact (1) should be fine but since it does have some global state you could run into problems in situation (2). Please file an issue in the repository if you'd like to discuss further.
This appears to be a bad link.
For someone encountering this at the moment - does anyone have any tips on identifying the cause and debugging the issue? I've used the check from the hooks page (how I discovered this) which confirms I've got 2 instances loaded: I believe I'm doing things by the book, in a monorepo react, react-dom etc are all always . What steps would you recommend after this?

// Check that the version we're exporting is the same one we expect in the // package. This is not an ideal way to do this, but makes sure that we keep // them in sync. <del> var reactVersionExp = /bReact.versions*=s*['"]([^'"]+)['"];/; </del> <ins> var reactVersionExp = /bREACT_VERSIONs*=s*['"]([^'"]+)['"];/; </ins> module.exports = function() { var reactVersion = reactVersionExp.exec(

'use strict'; <ins> var REACT_VERSION = '0.14.0-alpha'; var ExecutionEnvironment = require('ExecutionEnvironment'); var warning = require('warning'); if (__DEV__) { // before performing any initialization of React, check that // only one instance is in use on the current page. // // Using multiple instances cause a variety of problems if elements // from different versions are mixed on the same page. // // See issue #2402 if (ExecutionEnvironment.canUseDOM) { warning( typeof window.__REACT_VERSION__ === 'undefined', 'Multiple instances of React have been initialized on the same page. ' + 'Currently initializing React v' + REACT_VERSION + ' but another instance of React v' + window.__REACT_VERSION__ + ' was already initialized' ); window.__REACT_VERSION__ = REACT_VERSION; } } </ins> var ReactChildren = require('ReactChildren'); var ReactComponent = require('ReactComponent'); var ReactClass = require('ReactClass');

var assign = require('Object.assign'); var findDOMNode = require('findDOMNode'); var onlyChild = require('onlyChild'); <del> var warning = require('warning'); </del> ReactDefaultInjection.inject();

var render = ReactPerf.measure('React', 'render', ReactMount.render); var React = { <ins> version: REACT_VERSION, </ins> Children: { map: ReactChildren.map, forEach: ReactChildren.forEach,

} if (__DEV__) { <del> var ExecutionEnvironment = require('ExecutionEnvironment'); </del> if (ExecutionEnvironment.canUseDOM && window.top === window.self) { // If we're in Chrome, look for the devtools marker and provide a download

} } <del> React.version = '0.14.0-alpha'; </del> module.exports = React;


Question:
Docs here: And those ones taged as HTML5 are not in the list of supported tags:
, are in there. is handled at run time. The others are missing.
It seems autoFocus is not supported on server side rendering
The property should add the attribute to the html input element too. This is especially useful if you decide to do server-side rendering only. There shouldn’t be a conflict with the current JS code that handles auto focus on unsupported browsers.

draggable: null, encType: null, form: MUST_USE_ATTRIBUTE, <ins> formAction: MUST_USE_ATTRIBUTE, formEncType: MUST_USE_ATTRIBUTE, formMethod: MUST_USE_ATTRIBUTE, </ins> formNoValidate: HAS_BOOLEAN_VALUE, <ins> formTarget: MUST_USE_ATTRIBUTE, </ins> frameBorder: MUST_USE_ATTRIBUTE, headers: null, height: MUST_USE_ATTRIBUTE,


Question:
I've created a repo to help illustrate what I'm running into: Basically, developing in pure jsx and using the React.createFactory() are not interchangeable under testing using jest. This makes writing unit tests a little trickier. According to this link: , non-jsx components must be wrapped in a React.createFactory(). But, when testing these components using Jest, I've found that these are not interchangeable within tests that mock sub-modules. I'm guessing that the differences stem from using .bind() within React.createFactory:
updated the aforementioned repo with some possible workarounds. hopefully it saves someone else some time. perhaps the documentation can be expanded with an example.
cc
First of all, thank you for an excellent bug report. Very well structured and easy to test. The bad news is that the various wrappers and undoing of wrappers is very complex. It was difficult to get 0.12 into a form where it was a perfect upgrade path. I guess this is a special case where something broke down. I ended up spending a lot of time on this so I'm inclined to just leave 0.12 as broken. :/ The good news is that this works in the master branch so this will be fixed in 0.13. Would you mind submitting a formal pull request with these unit tests to our tests to ensure that it doesn't break again? The exception is asserting on props on mockComponent. We probably won't support that. is considered legacy at this point. It shouldn't be as important in 0.13, since auto-mocked components works better out-of-the-box. We'll probably encourage shallow testing for this use case.
i'll do my best to get the tests into a PR for your test suite. But, fighting some fires at the moment, so I can't promise a drop date. Thanks for looking into it.
Closing as very outdated.

}); }); <ins> describe('comparing jsx vs .createFactory() vs .createElement()', function() { var Child, mocks; beforeEach(function() { require('mock-modules').dumpCache(); mocks = require('mocks'); React = require('React'); ReactDOM = require('ReactDOM'); ReactTestUtils = require('ReactTestUtils'); var metaData = mocks.getMetadata(React.createClass({ render: function() { return React.createElement('div'); }, })); Child = mocks.generateFromMetadata(metaData); }); describe('when using jsx only', function() { var Parent, instance; beforeEach(function() { Parent = React.createClass({ render: function() { return ( <div> <Child ref="child" foo="foo value">children value</Child> </div> ); }, }); instance = ReactTestUtils.renderIntoDocument(<Parent/>); }); it('should scry children but cannot', function() { var children = ReactTestUtils.scryRenderedComponentsWithType(instance, Child); expect(children.length).toBe(1); }); it('does not maintain refs', function() { expect(instance.refs.child).not.toBeUndefined(); }); it('can capture Child instantiation calls', function() { expect(Child.mock.calls[0][0]).toEqual({ foo: 'foo value', children: 'children value' }); }); }); describe('when using parent that uses .createFactory()', function() { var factory, instance; beforeEach(function() { var childFactory = React.createFactory(Child); var Parent = React.createClass({ render: function() { return React.DOM.div({}, childFactory({ ref: 'child', foo: 'foo value' }, 'children value')); }, }); factory = React.createFactory(Parent); instance = ReactTestUtils.renderIntoDocument(factory()); }); it('can properly scry children', function() { var children = ReactTestUtils.scryRenderedComponentsWithType(instance, Child); expect(children.length).toBe(1); }); it('does not maintain refs', function() { expect(instance.refs.child).not.toBeUndefined(); }); it('can capture Child instantiation calls', function() { expect(Child.mock.calls[0][0]).toEqual({ foo: 'foo value', children: 'children value' }); }); }); describe('when using parent that uses .createElement()', function() { var factory, instance; beforeEach(function() { var Parent = React.createClass({ render: function() { return React.DOM.div({}, React.createElement(Child, { ref: 'child', foo: 'foo value' }, 'children value')); }, }); factory = React.createFactory(Parent); instance = ReactTestUtils.renderIntoDocument(factory()); }); it('should scry children but cannot', function() { var children = ReactTestUtils.scryRenderedComponentsWithType(instance, Child); expect(children.length).toBe(1); }); it('does not maintain refs', function() { expect(instance.refs.child).not.toBeUndefined(); }); it('can capture Child instantiation calls', function() { expect(Child.mock.calls[0][0]).toEqual({ foo: 'foo value', children: 'children value' }); }); }); }); </ins>