1 | # React Proxy [![build status](https://img.shields.io/travis/gaearon/react-proxy/master.svg?style=flat-square)](https://travis-ci.org/gaearon/react-proxy) [![npm version](https://img.shields.io/npm/v/react-proxy.svg?style=flat-square)](https://www.npmjs.com/package/react-proxy)
|
2 |
|
3 | A generic React component proxy useful for hot reloading.
|
4 |
|
5 | ## Requirements
|
6 |
|
7 | * React 0.14+
|
8 |
|
9 | ## Usage
|
10 |
|
11 | Intended to be used from hot reloading tools like React Hot Loader.
|
12 | If you’re an application developer, it’s unlikely you’ll want to use it directly.
|
13 |
|
14 | You will need something like [react-deep-force-update](https://github.com/gaearon/react-deep-force-update) to re-render the component tree after applying the update.
|
15 |
|
16 | ```js
|
17 | import React, { Component } from 'react';
|
18 |
|
19 | class ComponentVersion1 extends Component {
|
20 | render() {
|
21 | return <div>Before hot update.</div>;
|
22 | }
|
23 | }
|
24 |
|
25 | class ComponentVersion2 extends Component {
|
26 | render() {
|
27 | return <div>After hot update.</div>;
|
28 | }
|
29 | }
|
30 | ```
|
31 |
|
32 | Without React Proxy:
|
33 |
|
34 | ```js
|
35 | const rootEl = document.getElementById('root');
|
36 | React.render(<ComponentVersion1 />, rootEl);
|
37 |
|
38 | // Will reset state and kill DOM :-(
|
39 | React.render(<ComponentVersion2 />, rootEl);
|
40 | ```
|
41 |
|
42 | With React Proxy:
|
43 |
|
44 | ```js
|
45 | import React from 'react';
|
46 | import { render } from 'react-dom';
|
47 | import createProxy from 'react-proxy';
|
48 | import deepForceUpdate from 'react-deep-force-update';
|
49 |
|
50 | // Create a proxy object, given the initial React component class.
|
51 | const proxy = createProxy(ComponentVersion1);
|
52 |
|
53 | // Obtain a React class that acts exactly like the initial version.
|
54 | // This is what we'll use in our app instead of the real component class.
|
55 | const Proxy = proxy.get();
|
56 |
|
57 | // Render the component (proxy, really).
|
58 | const rootInstance = render(<Proxy />, rootEl);
|
59 |
|
60 | // Point the proxy to the new React component class by calling update().
|
61 | // Instances will stay mounted and their state will be intact, but their methods will be updated.
|
62 | proxy.update(ComponentVersion2);
|
63 |
|
64 | // Force-update the whole React component tree.
|
65 | // Until React provides an official DevTools API to do this,
|
66 | // you should keep the reference to the root instance(s).
|
67 | deepForceUpdate(rootInstance);
|
68 | ```
|
69 |
|
70 | ## React Native
|
71 |
|
72 | This will work with React Native when [facebook/react-native#2985](https://github.com/facebook/react-native/issues/2985) lands.
|
73 | For now, you can keep using 1.x.
|
74 |
|
75 | ## Features
|
76 |
|
77 | * Supports both classic (`React.createClass()`) and modern (ES6 classes) style
|
78 | * Supports inherited and base classes (although you shouldn’t use inheritance with React)
|
79 | * Supports classic `createClass()` autobinding and modern [`autobind-decorator`](https://github.com/andreypopp/autobind-decorator)
|
80 | * Contains an extensive test suite to avoid regressions
|
81 | * Preserves `displayName`
|
82 | * Preserves enumerability and writability of methods
|
83 | * Preserves `toString()` of methods
|
84 | * Replaces instance getters and setters
|
85 | * Replaces instance methods preserving their identity
|
86 | * Replaces bound instance methods preserving their identity
|
87 | * Because identity is preserved, instance methods already scheduled for `setInterval` or `setTimeout` are updated
|
88 | * Replaces static getters and setters
|
89 | * Replaces unbound static methods
|
90 | * Replaces static properties unless they were overwritten by code
|
91 |
|
92 | ## Known Limitations
|
93 |
|
94 | * Does not replace ES7 instance properties
|
95 | * Does not replace bound static methods
|
96 | * Replacing a method using [`autobind-decorator`](https://github.com/andreypopp/autobind-decorator) causes its identity to change
|
97 |
|
98 | ## Contributing
|
99 |
|
100 | 1. Clone the repository
|
101 | 2. Run `npm install`
|
102 | 3. Run `npm run test:watch`
|
103 | 4. Take a look at the existing tests
|
104 | 5. Add tests for the failing case you aim to fix and make them pass
|
105 | 6. Submit a PR!
|
106 |
|
107 | ## License
|
108 |
|
109 | MIT
|