The React Team has held a 2-days conference few days ago, on the January 28 & 29, to share the current state of art of their library. Here is its schedule http://conf.reactjs.com/schedule.html
I barely heard about React name before that. Then I looked at all the conference videos, because the more I watched, the more I was getting interested in. And it’s just amazing.
React is not a yet another Javascript framework, definitely not.
Old school
When you develop with HTML/JS, you basically have data in some kind of structure JS side coming from a server, and you want to represent them in your HTML. Multiple solutions:
- just using some jQuery to access the DOM and calling some JS methods of yours to :
-
$element = render(item)
// render the full item into the DOM using some template engine or not bindClickEvents($element)
- some methods to update only some parts of your element, such as
updateText($element)
,updatePhoto($element)
. You have the full control of what’s going on, it can’t be faster, no fancy stuff between my click and my call toupdateText()
. A lot of plugins work this way. But it’s can be very difficult to maintain, you are never sure of what’s the DOM looks like after the first render and other methods were called (because they update the DOM too), and the code can grow quickly. “I forgot to callback a method” “I can’t re-render the whole thing, it’s blinking”.
-
- using two-way bindings framework such as AngularJS or KnockoutJS. You have a model with some properties, and its associated view:
. The framework ensures the syncness between them. It’s very easy to start, automatically handle standard events, ensures the sync between your model and your view, handles list of items, you can externalize behaviors, reuses them. It’s a good opportunity to have clean code, and to keep logic separated. But you can have trouble with things: scopes, controllers, DOM references, integration with third-party libraries, you can run into some performance issues (long lists of items, frequent updates, large DOM changes), have some artefacts on the UI side.
You are a component
Then you have the React way. That does not solve everything, but it’s a very fresh new way to handle model/view syncness.
It’s a library developed by Facebook. They are using it on the small dialogs here and there (inspect the DOM of the instant chat on their websites for instance, you will see some data-reactid
all over the place), and Instagram uses it too. They decided to explain to everybody what is that, how it works, what it’s going to be.
React is a framework where you must create a specific component for anything you want to render. A component has some properties (its configuration, it’s immutable), a state (what changes), and a way to render itself, by itself (no external template, it’s IN its code)
this.on(‘change’, render)
So, you have an component Person
with a state property name
that implements its render()
such as return
. Each time this.state.name
will change, your method render()
will automatically be called again. If it renders something else that the current DOM state then the DOM will be modified. You probably notice the return
, that’s not pure Javascript, that’s JSX, a special file type provided to write DOM easily in a JS file, it’s kinda a template, we’ll talk about it later.
At first, it’s a bit scary. Re-render the whole thing for each tiny modification ? I was directly thinking : what about performance ? it’s going to read my whole code each time, renders everything just because I updated a tiny counter over there? But actually, performance are very good for some reasons :
- React only applies the difference between the result of
render()
and the actual DOM (it creates a virtual DOM in-memory, and has some super-uber optimizations to diff if I understand correctly). Meaning that’s only the minimal set of DOM mutation operations is applied (forget about$container.empty().append(...)
), thus, no slowdown at all (the less DOM mutation we do, the better we are!). -
You can tell to React that a component does not need to be re-render again because you know it’s not dirty (by implementing the function
shouldComponentUpdate
to returnfalse
according to some conditions of yours).
The big advantage I find is to have a unique way to render your item : you know exactly what to expect from a given component state, no external alterations are possible. You don’t need to write functions that changes only some parts of it to optimize the rendering and avoid blicking for instance, it’s not necessary. You can even write easily some unit testing, because you exactly know what output to expect according to a given input.
Example
Here is a small example just to have a break and read some code! Here is the jsbin.
var CtheuName = React.createClass({ getInitialState: function() { return { name: '?' }; }, render: function() { return (); }, changeName: function() { this.setState({ name: Math.random() > .5 ? 'Ctheu' : 'React' }); } }); React.render(, document.body);
Here is the initial result :
When you push the button, you have a fifty-fifty chance of displaying either “Hello I’m Chteu” or “Hello I’m React” in the .
Reading the code, I’m pretty sure you understand how that works.
-
React.render()
creates and renders my componentCtheuName
(name of the var I created byReact.createClass
) to the document body, passing{ prefix: "Hello I'm" }
as its properties - To init the initial state of component, React calls
getInitialState()
(remember,this.state
contains mutable values,this.props
contains readonly values) - Then
render()
got called and returns the DOM - Because this is the first time
render()
has been called, this DOM is directly injected into the browser DOM. - When the button is pushed,
changeName()
is called (there is a onClick handler on the button), the name in the state is changed, thereforce React callsrender()
- The result is compared to the current DOM, and it finds out that the only difference is the
value
of the input, therefore it updates it, nothing else.
The browser DOM looks like :
We can just see some data-reactid
that seems to represent the hierarchy (.0 contains .0.0 and .0.1).
Seems easy right ? Think of a bigger application such as a webstore. Everything is naturally reusable. This was a very simple example. React can do a lot more, a lot of add-ons already exist. You can use the same React codebase on the client side AND on the server side with NodeJS. Why do that ? For SEO mostly : on the first call, the server can return the whole page with its content (à la PHP), therefore the search engines have content to process. From there, you update the client side normally (if you have dynamic update, the new items will have the same appearance and features, it’s the same codebase!). Take a look here to see a real-time Twitter feed using this technique. You can extend your components by adding mixins to them, such as If you are using Chrome, you can install this extension : . It will add a new tab React in the debugger tools if you are looking at a React website. You can unit test the components without any simulation software. For instance, Facebook is using Jest (in a framework called react-router to handle the page routing of your application (hash or history) A lot of nice components carousel, syntax highlighting, datepicker, treeview, even bootstrap has been rebuilt for React An architecture called Flux to handle the data of your application http://facebook.github.io/flux/docs/overview.html, working perfectly with React. React can be used with Meteor as the rendering piece https://github.com/reactjs/react-meteor to build incredible fast applications Enjoy React !
You could have components such as :
–
that contains a list of Product
–
contains ProductPhotos
, ProductDetails
and ProductButtons
–
that contains a list of Product
(the same component as the one used in the Features and hints
I’ll just finish by listing some cool features already implemented or planned, to give you a taste !
without
onChange
gives : Warning: You provided a value
prop to a form field without an onChange
handler. This will render a read-only field. If the field should be mutable use defaultValue
. Otherwise, set either onChange
or readOnly
. Check the render method of MyComponent
React.createClass({ mixins: [PureRenderMixin], ...
. This one automatically avoid render()
to be called if the state of the component did not change. Check why.Relay
) to facilitate and manage the data the components need to do to get their data. The main issue was because of the hierarchy of components, you need to pass, the top component needs to pass necessary infos to its children and so on. So at the end, it’s a nightmare to maintain either because you have to pass a lot of stuff the intermediate components do not care, you don’t know anymore where the infos are used, it’s hard to refactor etc. GraphQL
is all about making that totally transparent.