|
|
@ -4,108 +4,98 @@ layout: post |
|
|
|
author: Pete Hunt |
|
|
|
--- |
|
|
|
|
|
|
|
There are a lot of JavaScript MVC frameworks out there. Why did we |
|
|
|
build React and why would you want to use it? |
|
|
|
There are a lot of JavaScript MVC frameworks out there. Why did we build React |
|
|
|
and why would you want to use it? |
|
|
|
|
|
|
|
|
|
|
|
## React is not an MVC framework. |
|
|
|
## React isn't an MVC framework. |
|
|
|
|
|
|
|
React is a library for building large complex user interfaces with |
|
|
|
many reusable components that handle events, present backend data, |
|
|
|
and accept user input. At the same time, React was built to integrate |
|
|
|
with legacy code and to support older browsers. |
|
|
|
It's a library designed for building big UIs. The type where you have lots of |
|
|
|
reusable components that are handling events, presenting backend data, and |
|
|
|
accepting user input. The type where you have to integrate with legacy code, and |
|
|
|
support legacy browsers. |
|
|
|
|
|
|
|
In the traditional MVC pattern, React is used to build the view. React |
|
|
|
lets you decide how to manage your data and business logic, be it |
|
|
|
outside of React components or within. |
|
|
|
In the traditional MVC pattern, React is used to build the view. React lets you |
|
|
|
decide how to manage your data and business logic, be it outside of React |
|
|
|
components or within. |
|
|
|
|
|
|
|
## React does not use templates. |
|
|
|
## React doesn't use templates. |
|
|
|
|
|
|
|
Traditionally, web application user interfaces are built using |
|
|
|
templates written in templating languages or HTML directives. These |
|
|
|
templates dictate the full set of abstractions that you are allowed to |
|
|
|
use to build the user interface. |
|
|
|
Traditionally, web application UIs are built using templates written in |
|
|
|
templating languages or HTML directives. These templates dictate the full set of |
|
|
|
abstractions that you are allowed to use to build the user interface. |
|
|
|
|
|
|
|
React approaches building user interfaces differently by breaking them |
|
|
|
down into smaller, composable and reusable **components**. Although |
|
|
|
this means we have JavaScript generating markup, we think this is an |
|
|
|
advantage over templates for a few reasons: |
|
|
|
React approaches building user interfaces differently by breaking them down into |
|
|
|
smaller, composable and reusable **components**. Although this means we have |
|
|
|
JavaScript generating markup, we think this is an advantage over templates for a |
|
|
|
few reasons: |
|
|
|
|
|
|
|
- **JavaScript is a flexible, powerful programming language with the |
|
|
|
ability to build abstractions.** This is incredibly important in |
|
|
|
large applications. |
|
|
|
- Logic and markup are intimately tied and are both part of the |
|
|
|
presentation layer. So we are unifying the presentation layer, not |
|
|
|
breaking separation of concerns. |
|
|
|
- Large projects usually do not use WYSIWYG editors for production |
|
|
|
code, so breaking apart markup from code creates friction without |
|
|
|
any real gain. |
|
|
|
- By baking an understanding of markup and content into JavaScript, |
|
|
|
there is **no manual string concatenation** and, thus, less surface |
|
|
|
area for XSS vulnerabilities. |
|
|
|
- **JavaScript is a flexible, powerful programming language with the ability to |
|
|
|
build abstractions.** This is incredibly important in large applications. |
|
|
|
- By unifying markup and logic with a common language, applications can |
|
|
|
implement more appropriate separations of concerns. |
|
|
|
- Large projects usually do not use WYSIWYG editors for production code, so |
|
|
|
breaking apart markup from code creates friction without any real gain. |
|
|
|
- By baking an understanding of markup and content into JavaScript, there's |
|
|
|
**no manual string concatenation** and therefore less surface area for XSS |
|
|
|
vulnerabilities. |
|
|
|
|
|
|
|
## React updates are dead simple. |
|
|
|
## Reactive updates are dead simple. |
|
|
|
|
|
|
|
React really shines when your data changes over time. |
|
|
|
|
|
|
|
In a traditional JavaScript application, you need to look at what data |
|
|
|
changed and imperatively make changes to the DOM to keep it up-to-date. |
|
|
|
Even AngularJS, which provides a declarative interface via directives |
|
|
|
and data binding, requires a linking function to manually update DOM |
|
|
|
nodes. (Remember, React components are flexible and expressive, much |
|
|
|
like directives and less like templates in AngularJS.) |
|
|
|
In a traditional JavaScript application, you need to look at what data changed |
|
|
|
and imperatively make changes to the DOM to keep it up-to-date. Even AngularJS, |
|
|
|
which provides a declarative interface via directives and data binding, requires |
|
|
|
a linking function to manually update DOM nodes. Remember, React components are |
|
|
|
flexible and expressive, much like directives and less like templates in |
|
|
|
AngularJS. |
|
|
|
|
|
|
|
React takes a different approach. |
|
|
|
|
|
|
|
When your component is first initialized, the `render()` method is |
|
|
|
called and a string of static HTML is inserted into the DOM. When your |
|
|
|
data changes, the `render()` method is called again. We simply diff |
|
|
|
the old return value with the new one and determine the fastest way to |
|
|
|
update the DOM. So if only a single attribute on a single element has |
|
|
|
changed, that is all that React updates. |
|
|
|
When your component is first initialized, the `render()` method is called and a |
|
|
|
string of static HTML is inserted into the DOM. When your data changes, the |
|
|
|
`render()` method is called again. We simply diff the old return value with the |
|
|
|
new one to determine the fastest way to update the DOM. So if only a single |
|
|
|
attribute on a single element changes, that's all that React updates. |
|
|
|
|
|
|
|
We call this process **reconciliation**. Check out |
|
|
|
[this jsFiddle](http://jsfiddle.net/fv6RD/3/) for an example of |
|
|
|
reconciliation in action. |
|
|
|
|
|
|
|
Reconciliation will usually be faster than handwritten code because |
|
|
|
React knows about the entire state of the page and can do cool tricks |
|
|
|
like batching reads and writes and picking the fastest subset of DOM |
|
|
|
mutations to perform. |
|
|
|
|
|
|
|
The way we are able to pull this off is by constructing a very fast, |
|
|
|
lightweight representation of the DOM which knows which parts are |
|
|
|
dirtied and which parts are clean. **The data returned from `render()` |
|
|
|
is neither a string nor a DOM node -- it is a lightweight description |
|
|
|
of what the DOM should look like.** |
|
|
|
|
|
|
|
Because this re-render is so fast (on the order of 1ms for TodoMVC), |
|
|
|
we do not need the end user to explicitly specify data bindings. We |
|
|
|
have found this to be an easier way to build apps. It is a lot like |
|
|
|
the early days of the dynamic web. Back then, you wrote simple |
|
|
|
presentational code and when your data changed, you simply refreshed |
|
|
|
the page. Today, React makes that refresh very fast and lightweight, |
|
|
|
and only the parts of the markup that need to be changed are changed. |
|
|
|
|
|
|
|
No other framework that we have seen does this. |
|
|
|
[this jsFiddle](http://jsfiddle.net/fv6RD/3/) for an example of reconciliation |
|
|
|
in action. |
|
|
|
|
|
|
|
Reconciliation will usually be faster than handwritten code because React knows |
|
|
|
about the entire state of the page and can do cool tricks like batching reads |
|
|
|
and writes and picking the fastest subset of DOM mutations to perform. |
|
|
|
|
|
|
|
The way we're able to pull this off is by constructing a very fast, lightweight |
|
|
|
representation of the DOM which knows which parts are dirtied and which parts |
|
|
|
are clean. **The data returned from `render()` is neither a string nor a DOM |
|
|
|
node -- it's a lightweight description of what the DOM should look like.** |
|
|
|
|
|
|
|
Because this re-render is so fast (on the order of 1ms for TodoMVC), we don't |
|
|
|
need the end user to explicitly specify data bindings. We've found this to be an |
|
|
|
easier way to build apps. It's a lot like the early days of the dynamic web. |
|
|
|
Back then, you wrote simple presentational code and when your data changed, you |
|
|
|
simply refreshed the page. Today, React makes that refresh very fast and |
|
|
|
lightweight, and only the parts of markup that need to be changed are changed. |
|
|
|
|
|
|
|
No other framework that we've seen has managed to decouple building UIs without |
|
|
|
being coupled with the DOM. |
|
|
|
|
|
|
|
## HTML is just the beginning. |
|
|
|
|
|
|
|
Since React makes very few assumptions about its environment, we can |
|
|
|
do some pretty cool things with it: |
|
|
|
Since React makes very few assumptions about its environment, we can do some |
|
|
|
pretty cool things with it: |
|
|
|
|
|
|
|
- Facebook has dynamic charts that render to `<canvas>` instead of |
|
|
|
HTML. |
|
|
|
- Facebook has dynamic charts that render to `<canvas>` instead of HTML. |
|
|
|
- Instagram is a "single page" web app built entirely with React and |
|
|
|
`Backbone.Router`. Designers regularly contribute React code with |
|
|
|
JSX. |
|
|
|
- We have built an internal prototype that runs React apps in a web |
|
|
|
worker. |
|
|
|
`Backbone.Router`. Designers regularly contribute React code with JSX. |
|
|
|
- We've built an internal prototype that runs React apps in a web worker. |
|
|
|
- You can run React |
|
|
|
[on the server](http://github.com/petehunt/react-server-rendering) |
|
|
|
for SEO, performance, code sharing and overall flexibility. |
|
|
|
- Events behave in a consistent, standards-compliant way in all |
|
|
|
browsers (including IE8) and automatically use |
|
|
|
- Events behave in a consistent, standards-compliant way in all browsers |
|
|
|
(including IE8) and automatically use |
|
|
|
[event delegation](http://davidwalsh.name/event-delegate). |
|
|
|
|
|
|
|
Head on over to |
|
|
|