React v0.11

July 17, 2014 by Paul O’Shannessy


Update: We missed a few important changes in our initial post and changelog. We've updated this post with details about Descriptors and Prop Type Validation.


We're really happy to announce the availability of React v0.11. There seems to be a lot of excitement already and we appreciate everybody who gave the release candidate a try over the weekend. We made a couple small changes in response to the feedback and issues filed. We enabled the destructuring assignment transform when using jsx --harmony, fixed a small regression with statics, and made sure we actually exposed the new API we said we were shipping: React.Children.count.

This version has been cooking for a couple months now and includes a wide array of bug fixes and features. We highlighted some of the most important changes below, along with the full changelog.

The release is available for download from the CDN:

We've also published version 0.11.0 of the react and react-tools packages on npm and the react package on bower.

Please try these builds out and file an issue on GitHub if you see anything awry.

getDefaultProps #

Starting in React 0.11, getDefaultProps() is called only once when React.createClass() is called, instead of each time a component is rendered. This means that getDefaultProps() can no longer vary its return value based on this.props and any objects will be shared across all instances. This change improves performance and will make it possible in the future to do PropTypes checks earlier in the rendering process, allowing us to give better error messages.

Rendering to null #

Since React's release, people have been using work arounds to "render nothing". Usually this means returning an empty <div/> or <span/>. Some people even got clever and started returning <noscript/> to avoid extraneous DOM nodes. We finally provided a "blessed" solution that allows developers to write meaningful code. Returning null is an explicit indication to React that you do not want anything rendered. Behind the scenes we make this work with a <noscript> element, though in the future we hope to not put anything in the document. In the mean time, <noscript> elements do not affect layout in any way, so you can feel safe using null today!

// Before
render: function() {
  if (!this.state.visible) {
    return <span/>;
  }
  // ...
}

// After
render: function() {
  if (!this.state.visible) {
    return null;
  }
  // ...
}

JSX Namespacing #

Another feature request we've been hearing for a long time is the ability to have namespaces in JSX. Given that JSX is just JavaScript, we didn't want to use XML namespacing. Instead we opted for a standard JS approach: object property access. Instead of assigning variables to access components stored in an object (such as a component library), you can now use the component directly as <Namespace.Component/>.

// Before
var UI = require('UI');
var UILayout = UI.Layout;
var UIButton = UI.Button;
var UILabel = UI.Label;

render: function() {
  return <UILayout><UIButton /><UILabel>text</UILabel></UILayout>;
}

// After
var UI = require('UI');

render: function() {
  return <UI.Layout><UI.Button /><UI.Label>text</UI.Label></UI.Layout>;
}

Improved keyboard event normalization #

Keyboard events now contain a normalized e.key value according to the DOM Level 3 Events spec, allowing you to write simpler key handling code that works in all browsers, such as:

handleKeyDown: function(e) {
  if (e.key === 'Enter') {
    // Handle enter key
  } else if (e.key === ' ') {
    // Handle spacebar
  } else if (e.key === 'ArrowLeft') {
    // Handle left arrow
  }
},

Keyboard and mouse events also now include a normalized e.getModifierState() that works consistently across browsers.

Descriptors #

In our v0.10 release notes, we called out that we were deprecating the existing behavior of the component function call (eg component = MyComponent(props, ...children) or component = <MyComponent prop={...}/>). Previously that would create an instance and React would modify that internally. You could store that reference and then call functions on it (eg component.setProps(...)). This no longer works. component in the above examples will be a descriptor and not an instance that can be operated on. The v0.10 release notes provide a complete example along with a migration path. The development builds also provided warnings if you called functions on descriptors.

Along with this change to descriptors, React.isValidComponent and React.PropTypes.component now actually validate that the value is a descriptor. Overwhelmingly, these functions are used to validate the value of MyComponent(), which as mentioned is now a descriptor, not a component instance. We opted to reduce code churn and make the migration to 0.11 as easy as possible. However, we realize this is has caused some confusion and we're working to make sure we are consistent with our terminology.

Prop Type Validation #

Previously React.PropTypes validation worked by simply logging to the console. Internally, each validator was responsible for doing this itself. Additionally, you could write a custom validator and the expectation was that you would also simply console.log your error message. Very shortly into the 0.11 cycle we changed this so that our validators return (not throw) an Error object. We then log the error.message property in a central place in ReactCompositeComponent. Overall the result is the same, but this provides a clearer intent in validation. In addition, to better transition into our descriptor factory changes, we also currently run prop type validation twice in development builds. As a result, custom validators doing their own logging result in duplicate messages. To update, simply return an Error with your message instead.

Changelog #

React Core #

Breaking Changes #

  • getDefaultProps() is now called once per class and shared across all instances
  • MyComponent() now returns a descriptor, not an instance
  • React.isValidComponent and React.PropTypes.component validate descriptors, not component instances.
  • Custom propType validators should return an Error instead of logging directly

New Features #

  • Rendering to null
  • Keyboard events include normalized e.key and e.getModifierState() properties
  • New normalized onBeforeInput event
  • React.Children.count has been added as a helper for counting the number of children

Bug Fixes #

  • Re-renders are batched in more cases
  • Events: e.view properly normalized
  • Added Support for more HTML attributes (coords, crossOrigin, download, hrefLang, mediaGroup, muted, scrolling, shape, srcSet, start, useMap)
  • Improved SVG support
    • Changing className on a mounted SVG component now works correctly
    • Added support for elements mask and tspan
    • Added support for attributes dx, dy, fillOpacity, fontFamily, fontSize, markerEnd, markerMid, markerStart, opacity, patternContentUnits, patternUnits, preserveAspectRatio, strokeDasharray, strokeOpacity
  • CSS property names with vendor prefixes (Webkit, ms, Moz, O) are now handled properly
  • Duplicate keys no longer cause a hard error; now a warning is logged (and only one of the children with the same key is shown)
  • img event listeners are now unbound properly, preventing the error "Two valid but unequal nodes with the same data-reactid"
  • Added explicit warning when missing polyfills

React With Addons #

  • PureRenderMixin: a mixin which helps optimize "pure" components
  • Perf: a new set of tools to help with performance analysis
  • Update: New $apply command to transform values
  • TransitionGroup bug fixes with null elements, Android

React NPM Module #

  • Now includes the pre-built packages under dist/.
  • envify is properly listed as a dependency instead of a peer dependency

JSX #

  • Added support for namespaces, eg <Components.Checkbox />
  • JSXTransformer
    • Enable the same harmony features available in the command line with <script type="text/jsx;harmony=true">
    • Scripts are downloaded in parallel for more speed. They are still executed in order (as you would expect with normal script tags)
    • Fixed a bug preventing sourcemaps from working in Firefox

React Tools Module #

  • Improved readme with usage and API information
  • Improved ES6 transforms available with --harmony option
  • Added --source-map-inline option to the jsx executable
  • New transformWithDetails API which gives access to the raw sourcemap data

React v0.11 RC

July 13, 2014 by Paul O’Shannessy


It's that time again… we're just about ready to ship a new React release! v0.11 includes a wide array of bug fixes and features. We highlighted some of the most important changes below, along with the full changelog.

The release candidate is available for download from the CDN:

We've also published version 0.11.0-rc1 of the react and react-tools packages on npm and the react package on bower.

Please try these builds out and file an issue on GitHub if you see anything awry.

getDefaultProps #

Starting in React 0.11, getDefaultProps() is called only once when React.createClass() is called, instead of each time a component is rendered. This means that getDefaultProps() can no longer vary its return value based on this.props and any objects will be shared across all instances. This change improves performance and will make it possible in the future to do PropTypes checks earlier in the rendering process, allowing us to give better error messages.

Rendering to null #

Since React's release, people have been using work arounds to "render nothing". Usually this means returning an empty <div/> or <span/>. Some people even got clever and started returning <noscript/> to avoid extraneous DOM nodes. We finally provided a "blessed" solution that allows developers to write meaningful code. Returning null is an explicit indication to React that you do not want anything rendered. Behind the scenes we make this work with a <noscript> element, though in the future we hope to not put anything in the document. In the mean time, <noscript> elements do not affect layout in any way, so you can feel safe using null today!

// Before
render: function() {
  if (!this.state.visible) {
    return <span/>;
  }
  // ...
}

// After
render: function() {
  if (!this.state.visible) {
    return null;
  }
  // ...
}

JSX Namespacing #

Another feature request we've been hearing for a long time is the ability to have namespaces in JSX. Given that JSX is just JavaScript, we didn't want to use XML namespacing. Instead we opted for a standard JS approach: object property access. Instead of assigning variables to access components stored in an object (such as a component library), you can now use the component directly as <Namespace.Component/>.

// Before
var UI = require('UI');
var UILayout = UI.Layout;
var UIButton = UI.Button;
var UILabel = UI.Label;

render: function() {
  return <UILayout><UIButton /><UILabel>text</UILabel></UILayout>;
}

// After
var UI = require('UI');

render: function() {
  return <UI.Layout><UI.Button /><UI.Label>text</UI.Label></UI.Layout>;
}

Improved keyboard event normalization #

Keyboard events now contain a normalized e.key value according to the DOM Level 3 Events spec, allowing you to write simpler key handling code that works in all browsers, such as:

handleKeyDown: function(e) {
  if (e.key === 'Enter') {
    // Handle enter key
  } else if (e.key === ' ') {
    // Handle spacebar
  } else if (e.key === 'ArrowLeft') {
    // Handle left arrow
  }
},

Keyboard and mouse events also now include a normalized e.getModifierState() that works consistently across browsers.

Changelog #

React Core #

Breaking Changes #

  • getDefaultProps() is now called once per class and shared across all instances

New Features #

  • Rendering to null
  • Keyboard events include normalized e.key and e.getModifierState() properties
  • New normalized onBeforeInput event
  • React.Children.count has been added as a helper for counting the number of children

Bug Fixes #

  • Re-renders are batched in more cases
  • Events: e.view properly normalized
  • Added Support for more HTML attributes (coords, crossOrigin, download, hrefLang, mediaGroup, muted, scrolling, shape, srcSet, start, useMap)
  • Improved SVG support
    • Changing className on a mounted SVG component now works correctly
    • Added support for elements mask and tspan
    • Added support for attributes dx, dy, fillOpacity, fontFamily, fontSize, markerEnd, markerMid, markerStart, opacity, patternContentUnits, patternUnits, preserveAspectRatio, strokeDasharray, strokeOpacity
  • CSS property names with vendor prefixes (Webkit, ms, Moz, O) are now handled properly
  • Duplicate keys no longer cause a hard error; now a warning is logged (and only one of the children with the same key is shown)
  • img event listeners are now unbound properly, preventing the error "Two valid but unequal nodes with the same data-reactid"
  • Added explicit warning when missing polyfills

React With Addons #

  • PureRenderMixin
  • Perf: a new set of tools to help with performance analysis
  • Update: New $apply command to transform values
  • TransitionGroup bug fixes with null elements, Android

React NPM Module #

  • Now includes the pre-built packages under dist/.
  • envify is properly listed as a dependency instead of a peer dependency

JSX #

  • Added support for namespaces, eg <Components.Checkbox />
  • JSXTransformer
    • Enable the same harmony features available in the command line with <script type="text/jsx;harmony=true">
    • Scripts are downloaded in parallel for more speed. They are still executed in order (as you would expect with normal script tags)
    • Fixed a bug preventing sourcemaps from working in Firefox

React Tools Module #

  • Improved readme with usage and API information
  • Improved ES6 transforms available with --harmony option
  • Added --source-map-inline option to the jsx executable
  • New transformWithDetails API which gives access to the raw sourcemap data

Community Round-up #19

June 27, 2014 by Cheng Lou


React Meetups! #

Ever wanted to find developers who also share the same interest in React than you? Recently, there has been a React Meetup in San Francisco (courtesy of Telmate), and one in London (courtesy of Stuart Harris, Cain Ullah and Zoe Merchant). These two events have been big successes; a second one in London is already planned.

If you don't live near San Francisco or London, why not start one in your community?

Complementary Tools #

In case you haven't seen it, we've consolidated the tooling solution around React on this wiki page. Some of the notable recent entries include:

These are some of the links that often pop up on the #reactjs IRC channel. If you made something that you think deserves to be shown on the wiki, feel free to add it!

React in Interesting Places #

The core concepts React themselves is something very valuable that the community is exploring and pushing further. A year ago, we wouldn't have imagined something like Bruce Hauman's Flappy Bird ClojureScript port, whose interactive programming has been made possible through React:

And don't forget Pete Hunt's Wolfenstein 3D rendering engine in React (source code). While it's nearly a year old, it's still a nice demo.

Give us a shoutout on IRC or React Google Groups if you've used React in some Interesting places.

Even More People Using React #

Prismatic #

Prismatic recently shrank their codebase fivefold with the help of React and its popular ClojureScript wrapper, Om. They detailed their very positive experience here.

Finally, the state is normalized: each piece of information is represented in a single place. Since React ensures consistency between the DOM and the application data, the programmer can focus on ensuring that the state properly stays up to date in response to user input. If the application state is normalized, then this consistency is guaranteed by definition, completely avoiding the possibility of an entire class of common bugs.

Adobe Brackets #

Kevin Dangoor works on Brackets, the open-source code editor. After writing his first impression on React, he followed up with another insightful article on how to gradually make the code transition, how to preserve the editor's good parts, and how to tune Brackets' tooling around JSX.

We don’t need to switch to React everywhere, all at once. It’s not a framework that imposes anything on the application structure. [...] Easy, iterative adoption is definitely something in React’s favor for us.

Storehouse #

Storehouse (Apple Design Award 2014)'s web presence is build with React. Here's an example story. Congratulations on the award!

Vim Awesome #

Vim Awesome, an open-source Vim plugins directory built on React, was just launched. Be sure to check out the source code if you're curious to see an example of how to build a small single-page React app.

Random Tweets #

One Year of Open-Source React

May 29, 2014 by Cheng Lou


Today marks the one-year open-source anniversary of React.

It’s been a crazy ride. 2.3k commits and 1.5k issues and pull requests later, we’re approaching version 1.0 and nearing 7k Github stars, with big names such as Khan Academy, New York Times, and Airbnb (and naturally, Facebook and Instagram) using React in production, and many more developers blogging their success stories with it. The roadmap gives a glimpse into the future of the library; exciting stuff lies ahead!

Every success has its story. React was born out of our frustration at existing solutions for building UIs. When it was first suggested at Facebook, few people thought that functionally re-rendering everything and diffing the results could ever perform well. However, support grew after we built the first implementation and people wrote their first components. When we open-sourced React, the initial reception was similarly skeptical. It challenges many pre-established conventions and received mostly disapproving first-impressions, intermingled with positive ones that often were votes of confidence in Facebook’s engineering capabilities. On an open, competitive platform such as the web, it's been hard to convince people to try React. JSX, in particular, filtered out a huge chunk of potential early adopters.

Fast forward one year, React has strongly grown in popularity. Special acknowledgments go to Khan Academy, the ClojureScript community, and established frameworks such as Ember and Angular for contributing to and debating on our work. We'd also like to thank all the individual contributors who have taken the time to help out over the past year. React, as a library and as a new paradigm on the web, wouldn't have gained as much traction without them. In the future, we will continue to try to set an example of what's possible to achieve when we rethink about current “best practices”.

Here’s to another year!

Flux: An Application Architecture for React

May 6, 2014 by Bill Fisher and Jing Chen


We recently spoke at one of f8's breakout session about Flux, a data flow architecture that works well with React. Check out the video here:

To summarize, Flux works well for us because the single directional data flow makes it easy to understand and modify an application as it becomes more complicated. We found that two-way data bindings lead to cascading updates, where changing one data model led to another data model updating, making it very difficult to predict what would change as the result of a single user interaction.

In Flux, the Dispatcher is a singleton that directs the flow of data and ensures that updates do not cascade. As an application grows, the Dispatcher becomes more vital, as it can also manage dependencies between stores by invoking the registered callbacks in a specific order.

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.

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 is available, along with more detailed documentation and a tutorial. Look for more examples to come in the future.