gaearon / react-hot-loader

Tweak React components in real time. (Deprecated: use Fast Refresh instead.)
http://gaearon.github.io/react-hot-loader/
MIT License
12.26k stars 801 forks source link

index.js:2178 React-hot-loader: reconciliation failed could not dive into * while some elements are still present in the tree. #1034

Open Nuruddinjr opened 6 years ago

Nuruddinjr commented 6 years ago

Description

I am getting following error for a nested component even parent has a key.

index.js:2178 React-hot-loader: reconciliation failed could not dive into [ Jul 20, 2018 5:01 pm ] while some elements are still present in the tree.
__stack_frame_overlay_proxy_console__ @ index.js:2178
error @ react-hot-loader.development.js:166
(anonymous) @ react-hot-loader.development.js:1266
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1308
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1308
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1323
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1308
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1323
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1323
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1308
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1308
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1323
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1308
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1323
hotReplacementRender @ react-hot-loader.development.js:1246
next @ react-hot-loader.development.js:1259
(anonymous) @ react-hot-loader.development.js:1323
hotReplacementRender @ react-hot-loader.development.js:1246
hotReplacementRender$1 @ react-hot-loader.development.js:1350
reconcileHotReplacement @ react-hot-loader.development.js:1359
renderReconciler @ react-hot-loader.development.js:1373
asyncReconciledRender @ react-hot-loader.development.js:1381
proxiedRender @ react-hot-loader.development.js:615
finishClassComponent @ react-dom.development.js:13085
updateClassComponent @ react-dom.development.js:13047
beginWork @ react-dom.development.js:13715
performUnitOfWork @ react-dom.development.js:15741
workLoop @ react-dom.development.js:15780
renderRoot @ react-dom.development.js:15820
performWorkOnRoot @ react-dom.development.js:16437
performWork @ react-dom.development.js:16358
performSyncWork @ react-dom.development.js:16330
requestWork @ react-dom.development.js:16230
scheduleWork$1 @ react-dom.development.js:16096
enqueueForceUpdate @ react-dom.development.js:11222
./node_modules/react/cjs/react.development.js.Component.forceUpdate @ react.development.js:291
(anonymous) @ react-hot-loader.development.js:1542
(anonymous) @ react-hot-loader.development.js:1541
setTimeout (async)
updateInstances @ react-hot-loader.development.js:1535
(anonymous) @ react-hot-loader.development.js:1557
hotSetStatus @ bootstrap 087c43a6c05b06efecf4:202
hotApply @ bootstrap 087c43a6c05b06efecf4:551
(anonymous) @ bootstrap 087c43a6c05b06efecf4:289
Promise.then (async)
hotUpdateDownloaded @ bootstrap 087c43a6c05b06efecf4:288
hotAddUpdateChunk @ bootstrap 087c43a6c05b06efecf4:265
webpackHotUpdateCallback @ bootstrap 087c43a6c05b06efecf4:7
(anonymous) @ 0.087c43a6c05b06efecf4.hot-update.js:1

Expected behavior

I think whole parent component should be rendered.

Actual behavior

Doesn't re-render component

Environment

React Hot Loader version:

Run these commands in the project folder and fill in their results:

  1. node -v: v10.7.0
  2. npm -v: 6.2.0

Then, specify:

  1. Operating system: MacOS 10.13.6
  2. Browser and version: Chrome Version 67.0.3396.99 (Official Build) (64-bit)

Reproducible Demo

Please take the time to create a new project that reproduces the issue. Here is my code, hot-loader is failing on lines 43-49, where CommentAuthor and CommentTime components are being rendered within a map (Console output: https://monosnap.com/file/BWtpuOYQBtULWpRf5qQnPRcg18K30h#embed)

https://codesandbox.io/embed/9312qo9k4o

theKashey commented 6 years ago

That's not a real error. Just the way RHL treat text nodes, and the way React doing it - is a bit different. The problem here is a bit different - React-Hot-Loader ignores non-children-based component trees. Content, Author and Time in this case. It actually might( not should ) lead just to internal component's state loss, but not to problems with re-rendering. I am afraid, but we don't a single test for cases like this.

I'll take a look on your example.

RyanCCollins commented 6 years ago

I am seeing this as well. Is there a setting to hide this error from the console?

theKashey commented 6 years ago

I just found that there is no simple way to disable this error, and the only way is to set wrong logLevel.

import {setConfig} from 'react-hot-loader';
setConfig({logLevel: 'no-errors-please'});

I will look into the code, look like I could just suspend those errors, if unprocessed part of a tree does not contain any components, thus that's not a bit deal to no process it.

ludwigbacklund commented 5 years ago

Would be cool to have this fixed! 😇

clayrisser commented 5 years ago

You can ignore just this error using the ignore-warnings npm module.

https://www.npmjs.com/package/ignore-warnings

import ignoreWarnings from 'ignore-warnings';

ignoreWarnings('error', [
  'reconciliation failed could not dive into'
]);
daviddelusenet commented 5 years ago

I'm getting this error since I've upgraded to Styled Components V4.

theKashey commented 5 years ago

@daviddelusenet - does this error lead to a real Error, or just trashing your console?

daviddelusenet commented 5 years ago

It trashes my console and the hot reloading also stops working.

More people are having the same problem: https://spectrum.chat/thread/1f4aaadf-8d9e-4d36-b7ff-2f58c756ab9a

philiiiiiipp commented 5 years ago

I am wondering if this is related to this bug, but when I am running my app with hot reloading and v4, all css seems to get reapplied the moment I start interacting with components.

You can reproduce this by changing css in the inspector before interacting with your app.

danielbayerlein commented 5 years ago

@probablyup Do you have any idea if this is due to @styled-components?

quantizor commented 5 years ago

@philiiiiiipp the reapplying css thing is a known bug that will be fixed shortly: https://github.com/styled-components/styled-components/pull/2188

As far as HMR goes, I'm not sure. Does RHL have any compat issues with React.forwardRef? That and using the new context implementation is the only real change that would affect HMR in v4.

theKashey commented 5 years ago

@probablyup - 🥇 💯 🙌 React.forwardRef! That's the problem!

Not I know that to fix.

thomasbertet commented 5 years ago

@theKashey Is this considered fixed with latest release ? ie. 4.6.0 ? I still see this error and was wondering if its on my side the issue or if this is still work to do on this. Thanks for your help & work on this library, we all appreciate what you do.

theKashey commented 5 years ago
kaiyoma commented 5 years ago

I just enabled React hot loading in my (rather large) app and I'm seeing this error a lot. When it shows up, I have to reload the page to get the app working properly again. I'm not using forwardRef and I'm not using "styled-components". Is there a fix here or is this still an open issue?

theKashey commented 5 years ago

@kaiyoma - provide details then. Or:

  1. set up react-hot/react-dom, to be able to disable the code broken for you
  2. set option disableHotRendererWhenInjected, to disable it
kaiyoma commented 5 years ago

@theKashey What details would you like? Unfortunately, I won't be able to make a sandbox repro for this because this is happening in a large enterprise app with lots of moving parts. We have a custom HOC for fetching data from a proprietary protocol. If I make changes to the HOC, or a component that uses it, sometimes hot reloading works, but sometimes it doesn't. So far, I haven't been able to find a pattern.

Disabling the hot renderer or disabling the broken code seems to defeat the purpose of using the hot reloader in the first place. At that point, I might as well disable hot reloading and refresh the page on every change, which is what we do now.

Is there more information somewhere about what this error message means?

theKashey commented 5 years ago

Is there more information somewhere about what this error message means?

Yes, hotReplacementRender does not work as expected

Disabling the hot renderer ... defeat the purpose of using the hot reloader in the first place.

Not quite. hotReplacementRender is a process when we are rendering app before react, to understand the update. If you disable it - HOCs and many other cases would break(would drop local state).

However - if you did setup "react-hot-dom"(hot-loader/react-dom or webpack plugin) you may safely disable it, and rely on comparison we injected into react-dom. Which is much more "safe".

hotReplacementRender is still covering more cases, but every day become more and more error prone. For example some libraries could read context value directly from react - and that's not supported.

With 16.8 It is more safe to disable our custom rendered, and we are looking forward to enable disableHotRendererWhenInjected, which will do that when possible, by default.

kaiyoma commented 5 years ago

Setting disableHotRendererWhenInjected: true basically undoes all the hot reloading:

Ignored an update to unaccepted module <filename>
[HMR] The following modules couldn't be hot updated: (They would need a full reload!)
theKashey commented 5 years ago

HMR and RHL are working on different layers:

Changing value of disableHotRendererWhenInjected will change after-update behavior, and only when it's safe to do. It does not affect HMR.

The problem you showed is bound to HMR, or some runtime exception, which prevented the update from being accepted (that should not be possible).

kaiyoma commented 5 years ago

Okay, thanks for the explanation. I guess I'll keep playing around with this.