Use React and JSX in ASP.NET MVC

April 4, 2014 by Daniel Lo Nigro


Today we're happy to announce the initial release of ReactJS.NET, which makes it easier to use React and JSX in .NET applications, focusing specifically on ASP.NET MVC web applications. It has several purposes:

  • On-the-fly JSX to JavaScript compilation. Simply reference JSX files and they will be compiled and cached server-side.
   <script src="@Url.Content("/Scripts/HelloWorld.jsx")"></script>
  • JSX to JavaScript compilation via popular minification/combination libraries (Cassette and ASP.NET Bundling and Minification). This is suggested for production websites.
  • Server-side component rendering to make your initial render super fast.

Even though we are focusing on ASP.NET MVC, ReactJS.NET can also be used in Web Forms applications as well as non-web applications (for example, in build scripts). ReactJS.NET currently only works on Microsoft .NET but we are working on support for Linux and Mac OS X via Mono as well.

Installation #

ReactJS.NET is packaged in NuGet. Simply run Install-Package React.Mvc4 in the package manager console or search NuGet for "React" to install it. See the documentation for more information. The GitHub project contains a sample website demonstrating all of the features.

Let us know what you think, and feel free to send through any feedback and report bugs on GitHub.

The Road to 1.0

March 28, 2014 by Paul O’Shannessy


When we launched React last spring, we purposefully decided not to call it 1.0. It was production ready, but we had plans to evolve APIs and behavior as we saw how people were using React, both internally and externally. We've learned a lot over the past 9 months and we've thought a lot about what 1.0 will mean for React. A couple weeks ago, I outlined several projects that we have planned to take us to 1.0 and beyond. Today I'm writing a bit more about them to give our users a better insight into our plans.

Our primary goal with 1.0 is to clarify our messaging and converge on an API that is aligned with our goals. In order to do that, we want to clean up bad patterns we've seen in use and really help enable developers write good code.

Descriptors #

The first part of this is what we're calling "descriptors". I talked about this briefly in our v0.10 announcements. The goal here is to separate our virtual DOM representation from our use of it. Simply, this means the return value of a component (e.g. React.DOM.div(), MyComponent()) will be a simple object containing the information React needs to render. Currently the object returned is actually linked to React's internal representation of the component and even directly to the DOM element. This has enabled some bad patterns that are quite contrary to how we want people to use React. That's our failure.

We added some warnings in v0.9 to start migrating some of these bad patterns. With v0.10 we'll catch more. You'll see more on this soon as we expect to ship v0.11 with descriptors.

API Cleanup #

This is really connected to everything. We want to keep the API as simple as possible and help developers fall into the pit of success. Enabling bad patterns with bad APIs is not success.

ES6 #

Before we even launched React publicly, members of the team were talking about how we could leverage ES6, namely classes, to improve the experience of creating React components. Calling React.createClass(...) isn't great. We don't quite have the right answer here yet, but we're close. We want to make sure we make this as simple as possible. It could look like this:

class MyComponent extends React.Component {
  render() {
    ...
  }
}

There are other features of ES6 we're already using in core. I'm sure we'll see more of that. The jsx executable we ship with react-tools already supports transforming many parts of ES6 into code that will run on older browsers.

Context #

While we haven't documented context, it exists in some form in React already. It exists as a way to pass values through a tree without having to use props at every single point. We've seen this need crop up time and time again, so we want to make this as easy as possible. Its use has performance tradeoffs, and there are known weaknesses in our implementation, so we want to make sure this is a solid feature.

Addons #

As you may know, we ship a separate build of React with some extra features we called "addons". While this has served us fine, it's not great for our users. It's made testing harder, but also results in more cache misses for people using a CDN. The problem we face is that many of these "addons" need access to parts of React that we don't expose publicly. Our goal is to ship each addon on its own and let each hook into React as needed. This would also allow others to write and distribute "addons".

Browser Support #

As much as we'd all like to stop supporting older browsers, it's not always possible. Facebook still supports IE8. While React won't support IE8 forever, our goal is to have 1.0 support IE8. Hopefully we can continue to abstract some of these rough parts.

Animations #

Finding a way to define animations in a declarative way is a hard problem. We've been exploring the space for a long time. We've introduced some half-measures to alleviate some use cases, but the larger problem remains. While we'd like to make this a part of 1.0, realistically we don't think we'll have a good solution in place.

Miscellaneous #

There are several other things I listed on our projects page that we're tracking. Some of them are internals and have no obvious outward effect (improve tests, repo separation, updated test runner). I encourage you to take a look.

React v0.10

March 21, 2014 by Paul O’Shannessy


Hot on the heels of the release candidate earlier this week, we're ready to call v0.10 done. The only major issue we discovered had to do with the react-tools package, which has been updated. We've copied over the changelog from the RC with some small clarifying changes.

The release is available for download from the CDN:

We've also published version 0.10.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.

Clone On Mount #

The main purpose of this release is to provide a smooth upgrade path as we evolve some of the implementation of core. In v0.9 we started warning in cases where you called methods on unmounted components. This is part of an effort to enforce the idea that the return value of a component (React.DOM.div(), MyComponent()) is in fact not a reference to the component instance React uses in the virtual DOM. The return value is instead a light-weight object that React knows how to use. Since the return value currently is a reference to the same object React uses internally, we need to make this transition in stages as many people have come to depend on this implementation detail.

In 0.10, we’re adding more warnings to catch a similar set of patterns. When a component is mounted we clone it and use that object for our internal representation. This allows us to capture calls you think you’re making to a mounted component. We’ll forward them on to the right object, but also warn you that this is breaking. See “Access to the Mounted Instance” on this page. Most of the time you can solve your pattern by using refs.

Storing a reference to your top level component is a pattern touched upon on that page, but another examples that demonstrates what we see a lot of:

// This is a common pattern. However instance here really refers to a
// "descriptor", not necessarily the mounted instance.
var instance = <MyComponent/>;
React.renderComponent(instance);
// ...
instance.setProps(...);

// The change here is very simple. The return value of renderComponent will be
// the mounted instance.
var instance = React.renderComponent(<MyComponent/>)
// ...
instance.setProps(...);

These warnings and method forwarding are only enabled in the development build. The production builds continue to work as they did in v0.9. We strongly encourage you to use the development builds to catch these warnings and fix the call sites.

The plan for v0.11 is that we will go fully to "descriptors". Method calls on the return value of MyComponent() will fail hard.

Changelog #

React Core #

New Features #

  • Added warnings to help migrate towards descriptors
  • Made it possible to server render without React-related markup (data-reactid, data-react-checksum). This DOM will not be mountable by React. Read the docs for React.renderComponentToStaticMarkup
  • Added support for more attributes:
    • srcSet for <img> to specify images at different pixel ratios
    • textAnchor for SVG

Bug Fixes #

  • Ensure all void elements don’t insert a closing tag into the markup.
  • Ensure className={false} behaves consistently
  • Ensure this.refs is defined, even if no refs are specified.

Addons #

react-tools #

  • Added an option argument to transform function. The only option supported is harmony, which behaves the same as jsx --harmony on the command line. This uses the ES6 transforms from jstransform.

React v0.10 RC

March 19, 2014 by Paul O’Shannessy


v0.9 has only been out for a month, but we’re getting ready to push out v0.10 already. Unlike v0.9 which took a long time, we don't have a long list of changes to talk about.

The release candidate is available for download from the CDN:

We've also published version 0.10.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.

Clone On Mount #

The main purpose of this release is to provide a smooth upgrade path as we evolve some of the implementation of core. In v0.9 we started warning in cases where you called methods on unmounted components. This is part of an effort to enforce the idea that the return value of a component (React.DOM.div(), MyComponent()) is in fact not a reference to the component instance React uses in the virtual DOM. The return value is instead a light-weight object that React knows how to use. Since the return value currently is a reference to the same object React uses internally, we need to make this transition in stages as many people have come to depend on this implementation detail.

In 0.10, we’re adding more warnings to catch a similar set of patterns. When a component is mounted we clone it and use that object for our internal representation. This allows us to capture calls you think you’re making to a mounted component. We’ll forward them on to the right object, but also warn you that this is breaking. See “Access to the Mounted Instance” on this page. Most of the time you can solve your pattern by using refs.

Storing a reference to your top level component is a pattern touched upon on that page, but another examples that demonstrates what we see a lot of:

// This is a common pattern. However instance here really refers to a
// "descriptor", not necessarily the mounted instance.
var instance = <MyComponent/>;
React.renderComponent(instance);
// ...
instance.setProps(...);

// The change here is very simple. The return value of renderComponent will be
// the mounted instance.
var instance = React.renderComponent(<MyComponent/>)
// ...
instance.setProps(...);

These warnings and method forwarding are only enabled in the development build. The production builds continue to work as they did in v0.9. We strongly encourage you to use the development builds to catch these warnings and fix the call sites.

The plan for v0.11 is that we will go fully to "descriptors". Method calls on the return value of MyComponent() will fail hard.

Changelog #

React Core #

New Features #

  • Added warnings to help migrate towards descriptors
  • Made it possible to server render without React-related markup (data-reactid, data-react-checksum). This DOM will not be mountable by React. Read the docs for React.renderComponentToStaticMarkup
  • Added support for more attributes:
    • srcSet for <img> to specify images at different pixel ratios
    • textAnchor for SVG

Bug Fixes #

  • Ensure all void elements don’t insert a closing tag into the markup.
  • Ensure className={false} behaves consistently
  • Ensure this.refs is defined, even if no refs are specified.

Addons #

react-tools #

  • Added an option argument to transform function. The only option supported is harmony, which behaves the same as jsx --harmony on the command line. This uses the ES6 transforms from jstransform.

Community Round-up #18

March 14, 2014 by Jonas Gebhardt


In this Round-up, we are taking a few closer looks at React's interplay with different frameworks and architectures.

"Little framework BIG splash" #

Let's start with yet another refreshing introduction to React: Craig Savolainen (@maedhr) walks through some first steps, demonstrating how to build a Google Maps component using React.

Architecting your app with react #

Brandon Konkle (@bkonkle) Architecting your app with react We're looking forward to part 2!

React is not a full MVC framework, and this is actually one of its strengths. Many who adopt React choose to do so alongside their favorite MVC framework, like Backbone. React has no opinions about routing or syncing data, so you can easily use your favorite tools to handle those aspects of your frontend application. You'll often see React used to manage specific parts of an application's UI and not others. React really shines, however, when you fully embrace its strategies and make it the core of your application's interface.

Read the full article...

React vs. async DOM manipulation #

Eliseu Monar (@eliseumds)'s post "ReactJS vs async concurrent rendering" is a great example of how React quite literally renders a whole array of common web development work(arounds) obsolete.

React, Scala and the Play Framework #

Matthias Nehlsen wrote a detailed introductory piece on React and the Play Framework, including a helpful architectural diagram of a typical React app.

Nehlsen's React frontend is the second implementation of his chat application's frontend, following an AngularJS version. Both implementations are functionally equivalent and offer some perspective on differences between the two frameworks.

In another article, he walks us through the process of using React with scala.js to implement app-wide undo functionality.

Also check out his talk at Ping Conference 2014, in which he walks through a lot of the previously content in great detail.

React and Backbone #

The folks over at Venmo are using React in conjunction with Backbone. Thomas Boyt (@thomasaboyt) wrote this detailed piece about why React and Backbone are "a fantastic pairing".

React vs. Ember #

Eric Berry (@coderberry) developed Ember equivalents for some of the official React examples. Read his post for a side-by-side comparison of the respective implementations: "Facebook React vs. Ember".

React and plain old HTML #

Daniel Lo Nigro (@Daniel15) created React-Magic, which leverages React to ajaxify plain old html pages and even allows CSS transitions between pageloads.

React-Magic intercepts all navigation (link clicks and form posts) and loads the requested page via an AJAX request. React is then used to "diff" the old HTML with the new HTML, and only update the parts of the DOM that have been changed.

Check out the project on GitHub...

On a related note, Reactize by Ross Allen (@ssorallen) is a similarly awesome project: A wrapper for Rails' Turbolinks, which seems to have inspired John Lynch (@johnrlynch) to then create a server-rendered version using the JSX transformer in Rails middleware.

React and Object.observe #

Check out François de Campredon's implementation of TodoMVC based on React and ES6's Object.observe.

React and Angular #

Ian Bicking (@ianbicking) of Mozilla Labs explains why he "decided to go with React instead of Angular.js".

ng-React Update #

David Chang works through some performance improvements of his ngReact project. His post "ng-React Update - React 0.9 and Angular Track By" includes some helpful advice on boosting render performance for Angular components.

Angular gives you a ton of functionality out of the box - a full MV* framework - and I am a big fan, but I'll admit that you need to know how to twist the right knobs to get performance.

That said, React gives you a very strong view component out of the box with the performance baked right in. Try as I did, I couldn't actually get it any faster. So pretty impressive stuff.

Read the full post...

React was also recently mentioned at ng-conf, where the Angular team commented on React's concept of the virtual DOM:

React and Web Components #

Jonathan Krause (@jonykrause) offers his thoughts regarding parallels between React and Web Components, highlighting the value of React's ability to render pages on the server practically for free.

Immutable React #

Peter Hausel shows how to build a Wikipedia auto-complete demo based on immutable data structures (similar to mori), really taking advantage of the framework's one-way reactive data binding:

Its truly reactive design makes DOM updates finally sane and when combined with persistent data structures one can experience JavaScript development like it was never done before.

Read the full post

D3 and React #

Ben Smith built some great SVG-based charting components using a little less of D3 and a little more of React: D3 and React - the future of charting components?

Om and React #

Josh Haberman (@joshhaberman) discusses performance differences between React, Om and traditional MVC frameworks in "A closer look at OM vs React performance".

Speaking of Om: Omchaya by Sean Grove (@sgrove) is a neat Cljs/Om example project.

Random Tweets #