UNPKG

6.05 kBMarkdownView Raw
1react-hot-api
2=========
3
4This is a generic library implementing hot reload for React components without unmounting or losing their state.
5
6**It is intended for build tool authors or adventurous folk and *not* for website development. For a reference implementation *that you can actually use*, check out [react-hot-loader](https://github.com/gaearon/react-hot-loader) for Webpack.**
7
8This library drives React hot-reload magic of **[react-hot-loader](https://github.com/gaearon/react-hot-loader)** but is not tied to Webpack itself, so alternative build systems that support hot-reloading individual modules can use it to implement **[live-editing for React components](http://gaearon.github.io/react-hot-loader/)**.
9
10**[See the video.](https://vimeo.com/100010922)**
11
12### API
13
14#### `makeHot: (ReactClass, persistentId?) => ReactClass`
15
16Registers a hot-reloadable React class. If you don't pass `persistentId`, it is inferred from `ReactClass.displayName` or `ReactClass.name` (for ES6 classes). When called for the first time, it will merely return the passed class. When called the next time with the same `persistentId`, will patch original class with the prototype of the new class, and return the original class.
17
18#### `require('react-hot-api'): (ReactMount) => makeHot`
19
20Invoke this once within each hot-reloadable module to obtain the function described above.
21You must pass the result between *all emitted versions of the same module* for hot reload to work.
22
23`ReactMount` corresponds to `react/lib/ReactMount` and needs to be passed by the caller.
24
25### Usage
26
27This library is not meant to be used directly, unless you're authoring a build tool like [react-hot-loader](https://github.com/gaearon/react-hot-loader).
28
29It only makes sense if your build tool of choice is capable of two things:
30
31* emitting next versions of the same module and evaluate them;
32* passing arbitrary JS objects from previous to the next version of the same module.
33
34I am only aware of [Webpack Hot Module Replacement](http://webpack.github.io/docs/hot-module-replacement.html) but eventually other implementations should arise.
35
36In which case, here's how you can tranform the source to use it:
37
38##### SomeComponent.js, first run
39
40```javascript
41var React = require('react');
42
43var SomeComponent = React.createClass({
44 render: function () {
45 return <p>Version 1</p>;
46 }
47});
48
49module.exports = SomeComponent;
50
51
52
53// ================================================
54// The code you might generate with your build tool
55// to hide hot reloading mechanics from user:
56
57var makeHot = SOME_STORAGE_SHARED_BETWEEN_VERSIONS_OF_SAME_MODULE.makeHot;
58if (!makeHot) {
59 // On the first run, we will get here
60 makeHot = SOME_STORAGE_SHARED_BETWEEN_VERSIONS_OF_SAME_MODULE.makeHot = require('react-hot-api')(require('react/lib/ReactMount'));
61}
62
63// Will merely register SomeComponent so it can later be patched
64module.exports = makeHot(module.exports);
65```
66
67##### SomeComponent.js, subsequent runs (emitted after user edits the source)
68```javascript
69var React = require('react');
70
71var SomeComponent = React.createClass({
72 render: function () {
73 return <p>Version 2</p>;
74 }
75});
76
77module.exports = SomeComponent;
78
79
80
81// ================================================
82// The code you might generate with your build tool
83// to hide hot reloading mechanics from user:
84
85var makeHot = SOME_STORAGE_SHARED_BETWEEN_VERSIONS_OF_SAME_MODULE.makeHot;
86if (!makeHot) {
87 // On the second run, we will *NOT* get here
88 makeHot = SOME_STORAGE_SHARED_BETWEEN_VERSIONS_OF_SAME_MODULE.makeHot = require('react-hot-api')(require('react/lib/ReactMount'));
89}
90
91// Will patch existing SomeComponent with updated methods, force re-rendering and return patched first version
92module.exports = makeHot(module.exports);
93```
94
95You may also give user some way to access `makeHot` in case they want to allow hot-reloading for arbitrary classes inside the module:
96
97##### AnonComponents.js
98```javascript
99// The user still doesn't need to know these lines are being inserted by the tool:
100var module.makeHot = SOME_STORAGE_SHARED_BETWEEN_VERSIONS_OF_SAME_MODULE.makeHot;
101if (!module.makeHot) {
102 // put the function into some sane place (e.g. module.makeHot) without relying on hidden variables
103 module.makeHot = SOME_STORAGE_SHARED_BETWEEN_VERSIONS_OF_SAME_MODULE.makeHot = require('react-hot-api')(require('react/lib/ReactMount'));
104}
105// You might generate the code above with your build tool
106// to hide hot reloading mechanics from user.
107// ================================================
108
109
110
111var React = require('react');
112
113function createLabelComponent(str) {
114 var cls = React.createClass({
115 render: function () {
116 return <span>{str}</span>;
117 }
118 });
119
120 // ... but you may give user freedom to do this:
121 if (module.makeHot) { // we're in development and makeHot is available
122 cls = module.makeHot(cls, str); // use parameter as unique ID for anon class
123 }
124
125 return cls;
126}
127
128// These will be hot-reloadable:
129var Foo = createLabelComponent('Foo');
130var Bar = createLabelComponent('Bar');
131```
132
133### Thanks
134
135* [Tobias Koppers](https://github.com/sokra) for Webpack and HMR;
136* [Johannes Lumpe](https://github.com/johanneslumpe) and [Ben Alpert](https://github.com/spicyj) for helping me come up with the original hot reloading approach I'm still using here;
137* [Omar Skalli](https://github.com/Chetane) for coming up with an approach for forcing tree update that is compatible with ES6 classes [just the moment I needed it most](https://twitter.com/dan_abramov/status/543174410493239297);
138* [Kyle Mathews](http://github.com/KyleAMathews) for being the first person to actually use hot loader and helping spread the word when it was in initial stages;
139* [Christopher Chedeau](https://github.com/vjeux) for retweeting my horrendously hacked together proof of concept video, overwhelming response from which gave me the incentive to actually finish this thing;
140* Bret Victor for making me think live editing should be the norm, although he probably hates what people do after watching his videos.