UNPKG

31.8 kBMarkdownView Raw
1# React Hot Loader
2
3[![Build Status][build-badge]][build] [![version][version-badge]][package]
4[![Code Coverage][coverage-badge]][coverage]
5[![MIT License][license-badge]][license]
6
7[![PRs Welcome][prs-badge]][prs] [![Chat][chat-badge]][chat]
8[![Backers on Open Collective][oc-backer-badge]](#backers)
9[![Sponsors on Open Collective][oc-sponsor-badge]](#sponsors)
10
11[![Watch on GitHub][github-watch-badge]][github-watch]
12[![Star on GitHub][github-star-badge]][github-star]
13
14Tweak React components in real time ⚛️⚡️
15
16Watch
17**[Dan Abramov's talk on Hot Reloading with Time Travel](https://www.youtube.com/watch?v=xsSnOQynTHs).**
18
19## Install
20
21```
22npm install react-hot-loader
23```
24
25> Note: You can safely install react-hot-loader as a regular dependency instead
26> of a dev dependency as it automatically ensures it is not executed in
27> production and the footprint is minimal.
28
29## Getting started
30
311. Add `react-hot-loader/babel` to your `.babelrc`:
32
33```js
34// .babelrc
35{
36 "plugins": ["react-hot-loader/babel"]
37}
38```
39
402. Mark your root component as _hot-exported_:
41
42```js
43// App.js
44import { hot } from 'react-hot-loader/root';
45const App = () => <div>Hello World!</div>;
46export default hot(App);
47```
48
493. Make sure `react-hot-loader` is required before `react` and `react-dom`:
50
51* or `import 'react-hot-loader'` in your main file (before React)
52* or prepend your webpack entry point with `react-hot-loader/patch`, for example:
53 ```js
54 // webpack.config.js
55 module.exports = {
56 entry: ['react-hot-loader/patch', './src'],
57 // ...
58 }
59 ```
60
614. If you need hooks support, use [`@hot-loader/react-dom`](#hot-loaderreact-dom)
62
63### Hook support
64
65Hooks would be auto updated on HMR if they _should_ be.
66There is only one condition for it - a non zero dependencies list.
67
68```js
69❄️ useState(initialState); // will never updated (preserve state)
70❄️ useEffect(effect); // no need to update, updated on every render
71❄️ useEffect(effect, []); // "on mount" hook. "Not changing the past"
72🔥 useEffect(effect, [anyDep]); // would be updated
73
74🔥 useEffect(effect, ["hot"]); // the simplest way to make hook reloadable
75```
76
77**Plus**
78
79* any hook would be reloaded on a function body change. Enabled by default, controlled by `reloadHooksOnBodyChange` option.
80* you may configure RHL to reload any hook by setting `reloadLifeCycleHooks` option to true.
81
82**To disable hooks reloading** - set configuration option:
83
84```js
85import { setConfig } from 'react-hot-loader';
86
87setConfig({
88 reloadHooks: false,
89});
90```
91
92With this option set **all** `useEffects`, `useCallbacks` and `useMemo` would be updated on Hot Module Replacement.
93
94### Hooks reset
95
96Hooks would be reset if their order changes. Adding, removing or moving around would
97cause a local tree remount.
98
99**Babel plugin is required** for this operation. Without it changing hook order would throw an error
100which would be propagated till the nearest class-based component.
101
102## `@hot-loader/react-dom`
103
104[`@hot-loader/react-dom`](https://github.com/hot-loader/react-dom) replaces the "react-dom" package of the same version, but with additional patches to support hot reloading.
105
106There are 2 ways to install it:
107
108* Use **yarn** name resolution, so `@hot-loader/react-dom` would be installed instead of `react-dom`
109
110```
111yarn add react-dom@npm:@hot-loader/react-dom
112```
113
114* Use [webpack aliases](https://webpack.js.org/configuration/resolve/#resolvealias)
115
116```
117yarn add @hot-loader/react-dom
118```
119
120```js
121// webpack.config.js
122module.exports = {
123 // ...
124 resolve: {
125 alias: {
126 'react-dom': '@hot-loader/react-dom'
127 }
128 }
129}
130```
131
132### Old API
133
134**Note:** There is also an old version of `hot`, used prior to version 4.5.4. **Please use the new one**,
135as it is much more resilient to js errors that you may make during development.
136
137Meanwhile, not all the bundlers are compatible with new `/root` API, for example **[parcel](http://parceljs.org/) is not**.
138
139React-Hot-Load will throw an error, asking you to use the old API, if such incompatibility would be detected.
140It is almost the same, but you have to pass `module` inside `hot`.
141
142```js
143import { hot } from 'react-hot-loader';
144const App = () => <div>Hello World!</div>;
145export default hot(module)(App);
146```
147
1483. [Run webpack with Hot Module Replacement](https://webpack.js.org/guides/hot-module-replacement/#enabling-hmr):
149
150```sh
151webpack-dev-server --hot
152```
153
154## Limitations
155
156* (that's the goal) React-Hot-Loader would not change the past, only update the present - no lifecycle event would be called on component update.
157 As a result - all the code changes, you may made among `componentWillUnmount` or `componentDidMount`, would be ignored for
158 already created components.
159* (that's the goal) React-Hot-Loader would not update any object, including component `state`.
160* (1%) React-Hot-Loader could not reply some changes you may made in components `constructors`. As long as
161 components would not be recreated - RHL have to _inject_ new data onto existing components, but there is no way to detect the actual change and the way reply it.
162 React-Hot-Loader knows what class method is, not how you created it. See #1001 for details.
163
164## Recipes
165
166### Migrating from [create-react-app](https://github.com/facebookincubator/create-react-app)
167
1681. Run `npm run eject`
1692. Install React Hot Loader (`npm install --save-dev react-hot-loader`)
1703. In `config/webpack.config.dev.js`, add `'react-hot-loader/babel'` to Babel
171 loader configuration. The loader should now look like:
172
173```js
174 {
175 test: /\.(js|jsx)$/,
176 include: paths.appSrc,
177 loader: require.resolve('babel-loader'),
178 options: {
179 // This is a feature of `babel-loader` for webpack (not Babel itself).
180 // It enables caching results in ./node_modules/.cache/babel-loader/
181 // directory for faster rebuilds.
182 cacheDirectory: true,
183 plugins: ['react-hot-loader/babel'],
184 },
185 }
186```
187
1884. Mark your App (`src/App.js`) as _hot-exported_:
189
190```js
191// ./containers/App.js
192import React from 'react';
193import { hot } from 'react-hot-loader';
194
195const App = () => <div>Hello World!</div>;
196
197export default hot(module)(App);
198```
199
200### Migrating from [create-react-app](https://github.com/facebookincubator/create-react-app) without ejecting
201
202Users [report](https://github.com/gaearon/react-hot-loader/pull/729#issuecomment-354097936), that it is possible to use [react-app-rewire-hot-loader](https://github.com/cdharris/react-app-rewire-hot-loader) to setup React-hot-loader without ejecting.
203
204### TypeScript
205
206As of version 4, React Hot Loader requires you to pass your code through [Babel](http://babeljs.io/) to transform it so that it can be hot-reloaded. This can be a pain point for TypeScript users, who usually do not need to integrate Babel as part of their build process.
207
208Fortunately, it's simpler than it may seem! Babel will happily parse TypeScript syntax and can act as an alternative to the TypeScript compiler, so you can safely replace `ts-loader` or `awesome-typescript-loader` in your Webpack configuration with `babel-loader`. Babel won't typecheck your code, but you can use [`fork-ts-checker-webpack-plugin`](https://github.com/Realytics/fork-ts-checker-webpack-plugin) (and/or invoke `tsc --noEmit`) as part of your build process instead.
209
210A sample configuration:
211
212```js
213{
214 // ...you'll probably need to configure the usual Webpack fields like "mode" and "entry", too.
215 resolve: { extensions: [".ts", ".tsx", ".js", ".jsx"] },
216 module: {
217 rules: [
218 {
219 test: /\.(j|t)sx?$/,
220 exclude: /node_modules/,
221 use: {
222 loader: "babel-loader",
223 options: {
224 cacheDirectory: true,
225 babelrc: false,
226 presets: [
227 [
228 "@babel/preset-env",
229 { targets: { browsers: "last 2 versions" } } // or whatever your project requires
230 ],
231 "@babel/preset-typescript",
232 "@babel/preset-react"
233 ],
234 plugins: [
235 // plugin-proposal-decorators is only needed if you're using experimental decorators in TypeScript
236 ["@babel/plugin-proposal-decorators", { legacy: true }],
237 ["@babel/plugin-proposal-class-properties", { loose: true }],
238 "react-hot-loader/babel"
239 ]
240 }
241 }
242 }
243 ]
244 },
245 plugins: [
246 new ForkTsCheckerWebpackPlugin()
247 ]
248};
249```
250
251For a full example configuration of TypeScript with React Hot Loader and newest beta version of Babel, check [here](https://github.com/gaearon/react-hot-loader/tree/master/examples/typescript).
252
253As an alternative to this approach, it's possible to chain Webpack loaders so that your code passes through Babel and then TypeScript (or TypeScript and then Babel), but this approach is not recommended as it is more complex and may be significantly less performant. Read more [discussion here](https://github.com/gaearon/react-hot-loader/issues/884).
254
255### Parcel
256
257Parcel supports Hot Module Reloading out of the box, just follow step 1 and 2 of [Getting Started](https://github.com/gaearon/react-hot-loader/tree/master#getting-started).
258
259We also have a [full example running Parcel + React Hot Loader](https://github.com/gaearon/react-hot-loader/tree/master/examples/parcel).
260
261### Electron
262
263You need something to mark your modules as hot in order to use React Hot Loader.
264
265One way of doing this with Electron is to simply use webpack like any web-based project might do and the general guide above describes. See also [this example Electron app](https://github.com/s-h-a-d-o-w/rhl-electron-quick-start).
266
267A webpack-less way of doing it to use `electron-compile` (which is also used by [`electron-forge`](https://electronforge.io)) - see [this example](https://github.com/rllola/hmr-example-issue-2). While it requires less configuration, something to keep in mind is that `electron-compile`'s HMR will always reload all modules, regardless of what was actually edited.
268
269### Source Maps
270
271If you use `devtool: 'source-map'` (or its equivalent), source maps will be
272emitted to hide hot reloading code.
273
274Source maps slow down your project. Use `devtool: 'eval'` for best build
275performance.
276
277Hot reloading code is just one line in the beginning and one line at the end of
278each module so you might not need source maps at all.
279
280### Linking
281
282If you are using `npm link` or `yarn link` for development purposes, there is a chance you will get error `Module not found: Error: Cannot resolve module 'react-hot-loader'` or the linked package is not hot reloaded.
283
284There are 2 ways to fix `Module not found`:
285
286* Use [`include` in loader configuration](https://github.com/gaearon/react-hot-boilerplate/blob/master/webpack.config.js#L22) to only opt-in your app's files to processing.
287* Alternatively if you are using webpack, override the module resolution in your config:
288
289```js
290{
291 resolve: {
292 alias: {
293 'react-hot-loader': path.resolve(path.join(__dirname, './node_modules/react-hot-loader')),
294 }
295 }
296}
297```
298
299And to make your linked package to be hot reloaded, it will need to use the patched version of `react` and `react-dom`, if you're using webpack, add this options to the alias config
300
301```js
302{
303 resolve: {
304 alias: {
305 'react-hot-loader': path.resolve(path.join(__dirname, './node_modules/react-hot-loader')),
306 // add these 2 lines below so linked package will reference the patched version of `react` and `react-dom`
307 'react': path.resolve(path.join(__dirname, './node_modules/react')),
308 'react-dom': path.resolve(path.join(__dirname, './node_modules/react-dom')),
309 // or point react-dom above to './node_modules/@hot-loader/react-dom' if you are using it
310 }
311 }
312}
313```
314
315## Preact
316
317React-hot-loader should work out of the box with `preact-compat`, but, in case of pure preact, you will need
318to configure it:
319
320* create configuration file (setupHotLoader.js)
321
322```js
323import reactHotLoader from 'react-hot-loader';
324import preact from 'preact';
325
326reactHotLoader.preact(preact);
327```
328
329* dont forget to import it
330
331#### Preact limitations
332
333* HOCs and Decorators as not supported yet. For Preact React-Hot-Loader v4 behave as v3.
334
335## React Native
336
337React Native
338**[supports hot reloading natively](https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html)**
339as of version 0.22.
340
341Using React Hot Loader with React Native can cause unexpected issues (see #824) and is not recommended.
342
343## Webpack plugin
344
345We recommend using the `babel` plugin, but there are some situations where you are unable to. If so, try the `webpack` plugin / `webpack-loader` (as seen in v3).
346
347Remember - the `webpack` plugin is **not compatible** with class-based components. The `babel` plugin
348will inject special methods to every class, to make `class members` (like onClick) hot-updatable, while the `webpack` plugin would leave classes as is, without any _instrumentation_.
349
350```js
351class MyComponent extends React.Component {
352 onClick = () => this.setState(); // COULD NOT UPDATE
353 variable = 1; // this is ok
354 render() {} // this is ok
355}
356```
357
358But `webpack-loader` could help with TypeScript or _spreading_ "cold API" [to all node_modules](https://github.com/gaearon/react-hot-loader#disabling-a-type-change-for-all-node_modules).
359
360> It is safe to enable this loader for all the files. But place it after babel-loader, if babel-loader is present.
361
362```js
363// webpack.config.js
364module.exports = {
365 module: {
366 rules: [
367 {
368 test: /\.jsx?$/,
369 include: /node_modules/,
370 use: ['react-hot-loader/webpack'],
371 },
372 ],
373 },
374};
375```
376
377Webpack plugin will also land a "hot" patch to react-dom, making React-Hot-Loader more compliant to [the principles](https://github.com/gaearon/react-hot-loader/issues/1118).
378
379If you are using `babel-plugin` you might not need to apply `webpack-loader` to all the files, scoping it to `react-dom`
380
381```js
382// would only land a "hot-patch" to react-dom
383{
384 test: /\.js$/,
385 include: /node_modules\/react-dom/,
386 use: ['react-hot-loader/webpack']
387},
388```
389
390### Code Splitting
391
392If you want to use Code Splitting + React Hot Loader, the simplest solution is to pick one of our compatible library:
393
394* [Loadable Components](https://github.com/smooth-code/loadable-components/)
395* [Imported Component](https://github.com/theKashey/react-imported-component)
396* [React Universal Component](https://github.com/faceyspacey/react-universal-component)
397* [React-Loadable](https://github.com/jamiebuilds/react-loadable)
398
399If you use a non-yet-friendly library, like [react-async-component](github.com/ctrlplusb/react-async-component) you have to mark all your "loaded components" as _hot-exported_:
400
401```js
402// AsyncHello.js
403import { asyncComponent } from 'react-async-component';
404
405// asyncComponent could not `hot-reload` itself.
406const AsyncHello = asyncComponent({
407 resolve: () => import('./Hello'),
408});
409
410export default AsyncHello;
411```
412
413```js
414// Hello.js
415import { hot } from 'react-hot-loader/root';
416
417const Hello = () => 'Hello';
418
419export default hot(Hello); // <-- module will reload itself
420```
421
422### Checking Element `type`s
423
424Because React Hot Loader creates proxied versions of your components, comparing
425reference types of elements won't work:
426
427```js
428const element = <Component />;
429console.log(element.type === Component); // false
430```
431
432React Hot Loader exposes a function `areComponentsEqual` to make it possible:
433
434```js
435import { areComponentsEqual } from 'react-hot-loader';
436const element = <Component />;
437areComponentsEqual(element.type, Component); // true
438```
439
440Another way - compare "rendered" element type
441
442```js
443const element = <Component />;
444console.log(element.type === <Component />.type); // true
445
446// better - precache rendered type
447const element = <Component />;
448const ComponentType = <Component />.type;
449console.log(element.type === ComponentType); // true
450```
451
452But you might have to provide all required props. See [original issue](https://github.com/gaearon/react-hot-loader/issues/304).
453This is most reliable way to compare components, but it will not work with required props.
454
455Another way - compare Component name.
456
457> Not all components has a name. **In production displayName could not exists.**
458
459```js
460const element = <Component />;
461console.log(element.displayName === 'Component'); // true
462```
463
464This is something we did not solve yet. Cold API could help keep original types.
465
466### Webpack ExtractTextPlugin
467
468webpack ExtractTextPlugin is not compatible with React Hot Loader. Please disable it in development:
469
470```js
471new ExtractTextPlugin({
472 filename: 'styles/[name].[contenthash].css',
473 disable: NODE_ENV !== 'production',
474});
475```
476
477#### Disabling a type change (❄️)
478
479It is possible to disable React-Hot-Loader for a specific component, especially to
480enable common way to type comparison.
481See #991 for the idea behind ⛄️, and #304 about "type comparison" problem.
482
483```js
484import { cold } from 'react-hot-loader';
485
486cold(SomeComponent) // this component will ignored by React-Hot-Loader
487<SomeComponent />.type === SomeComponent // true
488```
489
490If you will update `cold` component React-Hot-Loader will complain (on error level), and then
491React will cold-replace Component with a internal state lose.
492
493> Reach-Hot-Loader: cold element got updated
494
495##### Disabling a type change for all node_modules
496
497You may _cold_ all components from node_modules. This will not work for HOC(like Redux) or dynamically created Components, but might help in most of situations, when type changes
498are not welcomed, and modules are not expected to change.
499
500```js
501import { setConfig, cold } from 'react-hot-loader';
502setConfig({
503 onComponentRegister: (type, name, file) => file.indexOf('node_modules') > 0 && cold(type),
504
505 // some components are not visible as top level variables,
506 // thus its not known where they were created
507 onComponentCreate: (type, name) => name.indexOf('styled') > 0 && cold(type),
508});
509```
510
511! To be able to "cold" components from 'node_modules' you have to apply babel to node_modules, while this
512folder is usually excluded.
513You may add one more babel-loader, with only one React-Hot-Loader plugin inside to solve this.
514**Consider using webpack-loader** for this.
515
516##### React-Hooks
517
518React hooks are not _really_ supported by React-Hot-Loader. Mostly due to our internal
519processes of re-rendering React Tree, which is required to reconcile an updated application
520before React will try to rerender it, and fail to do that, obviously.
521
522* hooks **should work** for versions 4.6.0 and above (`pureSFC` is enabled by default).
523* hooks will produce **errors** on every hot-update without patches to `react-dom`.
524* hooks **may loss the state** without patches to `react-dom`.
525* hooks does not support adding new hooks on the fly
526* change in hooks for a mounted components will cause a runtime exception, and a `retry` button (at the nearest class component) will be shown.
527 Pressing a `retry` button will basically remount tree branch.
528
529To mitigate any hook-related issues (and disable their hot-reloadability) - `cold` them.
530
531* _cold_ components using hooks.
532
533```js
534import { setConfig, cold } from 'react-hot-loader';
535setConfig({
536 onComponentCreate: (type, name) =>
537 (String(type).indexOf('useState') > 0 || String(type).indexOf('useEffect') > 0) && cold(type),
538});
539```
540
541## API
542
543### `hot(Component, options)`
544
545Mark a component as hot.
546
547#### Babel plugin
548
549Right now babel plugin has only one option, enabled by default.
550
551* `safetyNet` - will help you properly setup ReactHotLoader.
552
553You may disable it to get more control on the module execution order.
554
555```js
556//.babelrc
557{
558 "plugins": [
559 [
560 "react-hot-loader/babel",
561 {
562 "safetyNet": false
563 }
564 ]
565 ]
566}
567```
568
569#### Important
570
571**!!** Use `hot` only for module `exports`, not for module `imports`. **!!**
572
573```js
574import { hot } from 'react-hot-loader/root';
575
576const App = () => 'Hello World!';
577
578export default hot(App);
579```
580
581Keep in mind - by importing `react-hot-loader/root` you are setting up a boundary for update event propagation.
582
583The higher(in module hierarchy) you have it - the more stuff would be updated on Hot Module Replacement.
584
585To make RHL more reliable and safe, please place `hot` _below_ (ie somewhere in _imported_ modules):
586
587* react-dom
588* redux store creation
589* any data, you want to preserve between updates
590* big libraries
591
592You may(but it's not required) place `hot` to the every route/page/feature/lazy chunk, thus make updates more scoped.
593
594You don't need to wrap every component with `hot`, application work work fine with a single one.
595
596### (old)`hot(module, options)(Component, options)`
597
598Mark a component as hot. The "new" hot is just hidding the first part - `hot(module)`, giving you
599only the second `(App)`. The "new" hot is using old API.
600
601```js
602import { hot } from 'react-hot-loader';
603
604const App = () => 'Hello World!';
605
606export default hot(module)(App);
607```
608
609### `AppContainer`
610
611Mark application as hot reloadable. (**Prefer** using `hot` helper, see below for migration details).
612
613This low-level approach lets you make **hot **imports\_\_, not exports.
614
615```js
616import React from 'react';
617import ReactDOM from 'react-dom';
618import { AppContainer } from 'react-hot-loader';
619import App from './containers/App';
620
621const render = Component => {
622 ReactDOM.render(
623 <AppContainer>
624 <Component />
625 </AppContainer>,
626 document.getElementById('root'),
627 );
628};
629
630render(App);
631
632// webpack Hot Module Replacement API
633if (module.hot) {
634 // keep in mind - here you are configuring HMR to accept CHILDREN MODULE
635 // while `hot` would configure HMR for the CURRENT module
636 module.hot.accept('./containers/App', () => {
637 // if you are using harmony modules ({modules:false})
638 render(App);
639 // in all other cases - re-require App manually
640 render(require('./containers/App'));
641 });
642}
643```
644
645### areComponentsEqual(Component1, Component2)
646
647Test if two components have the same type.
648
649```js
650import { areComponentsEqual } from 'react-hot-loader';
651import Component1 from './Component1';
652import Component2 from './Component2';
653
654areComponentsEqual(Component1, Component2); // true or false
655```
656
657### setConfig(config)
658
659Set a new configuration for React Hot Loader.
660
661Available options are:
662
663* `logLevel`: specify log level, default to `"error"`, available values are: `['debug', 'log', 'warn', 'error']`
664* `pureSFC`: enable Stateless Functional Component. If disabled they will be converted to React Components.
665 Default value: false.
666* `ignoreSFC`: skip "patch" for SFC. "Hot loading" could still work, with webpack-patch present
667* `pureRender`: do not amend `render` method of any component.
668* for the rest see [index.d.ts](https://github.com/gaearon/react-hot-loader/blob/master/index.d.ts#L62-L133).
669
670```js
671// rhlConfig.js
672import { setConfig } from 'react-hot-loader';
673
674setConfig({ logLevel: 'debug' });
675```
676
677**It is important** to set configuration before any other action will take a place
678
679```js
680// index.js
681import './rhlConfig' // <-- extract configuration to a separate file, and import it in the beggining
682import React from 'react'
683....
684```
685
686## Migrating from v3
687
688### AppContainer vs hot
689
690Prior v4 the right way to setup React Hot Loader was to wrap your Application
691with `AppContainer`, set setup module acceptance by yourself. This approach is
692still valid but only for advanced use cases, prefer using `hot` helper.
693
694**React Hot Loader v3:**
695
696```js
697// App.js
698import React from 'react';
699
700const App = () => <div>Hello world!</div>;
701
702export default App;
703```
704
705```js
706// main.js
707import React from 'react';
708import ReactDOM from 'react-dom';
709import { AppContainer } from 'react-hot-loader';
710import App from './containers/App';
711
712const render = Component => {
713 ReactDOM.render(
714 <AppContainer>
715 <Component />
716 </AppContainer>,
717 document.getElementById('root'),
718 );
719};
720
721render(App);
722
723// webpack Hot Module Replacement API
724if (module.hot) {
725 module.hot.accept('./containers/App', () => {
726 // if you are using harmony modules ({modules:false})
727 render(App);
728 // in all other cases - re-require App manually
729 render(require('./containers/App'));
730 });
731}
732```
733
734**React Hot Loader v4:**
735
736```js
737// App.js
738import React from 'react';
739import { hot } from 'react-hot-loader';
740
741const App = () => <div>Hello world!</div>;
742
743export default hot(module)(App);
744```
745
746```js
747// main.js
748import React from 'react';
749import ReactDOM from 'react-dom';
750import App from './containers/App';
751
752ReactDOM.render(<App />, document.getElementById('root'));
753```
754
755### Patch is optional
756
757> Since 4.0 till 4.8
758
759Code is automatically patched, you can safely remove `react-hot-loader/patch` from your webpack config,
760if react-hot-loader is required before React in any other way.
761
762### Error Boundary is inside every component
763
764> Since 4.5.4
765
766On Hot Module Update we will inject `componentDidCatch` and a _special_ `render`
767to every Class-based component you have, making [Error Boundaries](https://reactjs.org/docs/error-boundaries.html#introducing-error-boundaries) more local.
768
769After update we will remove all sugar, keeping only Boundaries you've created.
770
771You can provide your own `errorReporter`, via `setConfig({errorReporter})` or opt-out from
772root ErrorBoundaries setting `errorBoundary={false}` prop on `AppContainer` or `hot`.
773However - this option affects only SFC behavior, and any ClassComponent would boundary itself.
774
775```js
776import { setConfig } from 'react-hot-loader';
777import ErrorBoundary from './ErrorBoundary';
778
779// ErrorBoundary will be given error and errorInfo prop.
780setConfig({ errorReporter: ErrorBoundary });
781```
782
783If `errorReporter` is not set - full screen error overlay would be shown.
784
785#### Setting global Error Reporter
786
787Global Error Reporter would, created a fixed overlay on top the page,
788would be used to display errors, not handled by `errorReporter`, and
789any HMR error.
790
791You may change, or disable this global error overlay
792
793```js
794// to disable
795setConfig({ ErrorOverlay: () => null });
796
797// to change
798setConfig({ ErrorOverlay: MyErrorOverlay });
799```
800
801The UX of existing overlay is a subject to change, and we are open to any proposals.
802
803## Known limitations and side effects
804
805### Note about `hot`
806
807`hot` accepts only React Component (Stateful or Stateless), resulting the `HotExported` variant of it.
808The `hot` function will setup current module to _self-accept_ itself on reload, and will **ignore** all the changes, made for non-React components.
809You may mark as many modules as you want. But `HotExportedComponent` **should be the only used export** of a _hot_-module.
810
811> Note: Please note how often we have used `exported` keyword. `hot` is for exports.
812
813> Note: Does nothing in production mode, just passes App through.
814
815### New Components keep executing the old code
816
817There is no way to hot-update constructor code, as result even new components
818will be born as the first ones, and then grow into the last ones. As of today, this issue cannot be solved.
819
820## Troubleshooting
821
822If it doesn't work, in 99% of cases it's a configuration issue. A missing option, a
823wrong path or port. webpack is very strict about configuration, and the best way
824to find out what's wrong is to compare your project to an already working setup,
825check out
826**[examples](https://github.com/gaearon/react-hot-loader/tree/master/examples)**,
827bit by bit.
828
829If something doesn't work, in 99% of cases it's an issue with your code. The Component
830didn't get registered, due to HOC or Decorator around it, which is making it
831invisible to the Babel plugin or webpack loader.
832
833We're also gathering
834**[Troubleshooting Recipes](https://github.com/gaearon/react-hot-loader/blob/master/docs/Troubleshooting.md)**
835so send a PR if you have a lesson to share!
836
837### Switch into debug mode
838
839Debug mode adds additional warnings and can tells you why React Hot Loader is
840not working properly in your application.
841
842```js
843import { setConfig } from 'react-hot-loader';
844setConfig({ logLevel: 'debug' });
845```
846
847## Contributors
848
849This project exists thanks to all the people who contribute. [Contribute](CONTRIBUTING.md).
850[![contributors][oc-contributors-img]](https://github.com/gaearon/react-hot-loader/graphs/contributors)
851
852## Backers
853
854Thank you to all our backers! 🙏 [Become a backer][oc-backer-link]
855[![backers][oc-backer-img]][oc-backer-link]
856
857## Sponsors
858
859Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor][oc-sponsor-link]
860
861<a href="https://opencollective.com/react-hot-loader/sponsor/0/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/0/avatar.svg"></a>
862<a href="https://opencollective.com/react-hot-loader/sponsor/1/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/1/avatar.svg"></a>
863<a href="https://opencollective.com/react-hot-loader/sponsor/2/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/2/avatar.svg"></a>
864<a href="https://opencollective.com/react-hot-loader/sponsor/3/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/3/avatar.svg"></a>
865<a href="https://opencollective.com/react-hot-loader/sponsor/4/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/4/avatar.svg"></a>
866<a href="https://opencollective.com/react-hot-loader/sponsor/5/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/5/avatar.svg"></a>
867<a href="https://opencollective.com/react-hot-loader/sponsor/6/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/6/avatar.svg"></a>
868<a href="https://opencollective.com/react-hot-loader/sponsor/7/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/7/avatar.svg"></a>
869<a href="https://opencollective.com/react-hot-loader/sponsor/8/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/8/avatar.svg"></a>
870<a href="https://opencollective.com/react-hot-loader/sponsor/9/website" target="_blank"><img src="https://opencollective.com/react-hot-loader/sponsor/9/avatar.svg"></a>
871
872## License
873
874MIT
875
876[build-badge]: https://img.shields.io/travis/gaearon/react-hot-loader.svg?style=flat-square
877[build]: https://travis-ci.org/gaearon/react-hot-loader
878[coverage-badge]: https://img.shields.io/codecov/c/github/gaearon/react-hot-loader.svg?style=flat-square
879[coverage]: https://codecov.io/github/gaearon/react-hot-loader
880[version-badge]: https://img.shields.io/npm/v/react-hot-loader.svg?style=flat-square
881[package]: https://www.npmjs.com/package/react-hot-loader
882[license-badge]: https://img.shields.io/npm/l/react-hot-loader.svg?style=flat-square
883[license]: https://github.com/gaearon/react-hot-loader/blob/next/LICENSE
884[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
885[prs]: http://makeapullrequest.com
886[chat]: https://gitter.im/gaearon/react-hot-loader
887[chat-badge]: https://img.shields.io/gitter/room/gaearon/react-hot-loader.svg?style=flat-square
888[github-watch-badge]: https://img.shields.io/github/watchers/gaearon/react-hot-loader.svg?style=social
889[github-watch]: https://github.com/gaearon/react-hot-loader/watchers
890[github-star-badge]: https://img.shields.io/github/stars/gaearon/react-hot-loader.svg?style=social
891[github-star]: https://github.com/gaearon/react-hot-loader/stargazers
892[oc-backer-badge]: https://opencollective.com/react-hot-loader/backers/badge.svg
893[oc-sponsor-badge]: https://opencollective.com/react-hot-loader/sponsors/badge.svg
894[oc-contributors-img]: https://opencollective.com/react-hot-loader/contributors.svg?width=890&button=false
895[oc-backer-img]: https://opencollective.com/react-hot-loader/backers.svg?width=890
896[oc-backer-link]: https://opencollective.com/react-hot-loader#backers
897[oc-sponsor-link]: https://opencollective.com/react-hot-loader#sponsor