Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It doesn't work with React.lazy #1425

Open
rainydayDY opened this issue Feb 26, 2020 · 15 comments · Fixed by backstage/backstage#4938
Open

It doesn't work with React.lazy #1425

rainydayDY opened this issue Feb 26, 2020 · 15 comments · Fixed by backstage/backstage#4938

Comments

@rainydayDY
Copy link

rainydayDY commented Feb 26, 2020

If you are reporting a bug or having an issue setting up React Hot Loader, please fill in below. For feature requests, feel free to remove this template entirely.

Description

What you are reporting: when I user React.lazy, it doesn't work

Expected behavior

What you think should happen: state can remain

Actual behavior

What actually happens: state can't remain

Environment

React Hot Loader version: 4.12.19
"devDependencies": {
"@babel/core": "^7.8.3",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-decorators": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"@babel/preset-react": "^7.8.3",
"babel-loader": "^8.0.6",
"express": "^4.17.1",
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
"webpack-dev-middleware": "^3.7.2",
"webpack-dev-server": "^3.10.3",
"webpack-hot-middleware": "^2.25.0"
},
"dependencies": {
"@babel/runtime-corejs3": "^7.8.3",
"connected-react-router": "^6.7.0",
"history": "^4.10.1",
"prop-types": "^15.7.2",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-hot-loader": "^4.12.19",
"react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0"
}

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

  1. node -v: v12.15.0
  2. npm -v: 6.13.4

Then, specify:

  1. Operating system: mac os
  2. Browser and version: chrome

Reproducible Demo

Please take the time to create a new project that reproduces the issue.

You can copy your project that experiences the problem and start removing things until you’re left with the minimal reproducible demo. This helps contributors, and you might get to the root of your problem during that process.

Push to GitHub and paste the link here.

you can use my project and reappear it : https://github.com/rainydayDY/webpack-fe

@theKashey
Copy link
Collaborator

Your example is too big. I've just checked this example and it works perfectly.

However there are two "modes" RHL can handle lazy with. Please try another one.
See Out-of-bound warning

If the tail update detection is not something you want or need, you can disable this behaviour by setting setConfig({ trackTailUpdates:false }).

By disabling trackTailUpdates you will activate another mode with a bit more aggressive lazy management.

@xyy94813
Copy link

xyy94813 commented May 5, 2020

@theKashey
how to run the example ??

I run the newest example with error in browser:

Uncaught TypeError: realPolyfill is not a function
    at eval (react-hot-loader.development.js:1379)
    at Object../node_modules/react-hot-loader/dist/react-hot-loader.development.js (bundle.js:1676)
    at __webpack_require__ (bundle.js:725)
    at fn (bundle.js:102)
    at eval (index.js:19)
    at Object../node_modules/react-hot-loader/index.js (bundle.js:1700)
    at __webpack_require__ (bundle.js:725)
    at fn (bundle.js:102)
    at eval (react-lifecycles-compat.es.js:8)
    at Object.eval (react-lifecycles-compat.es.js:10)

@xyy94813
Copy link

xyy94813 commented May 6, 2020

Someone say it maybe @hot-loader/react-dom problem.
hot-loader/react-dom#8 (comment)

But, It is not work for me without using @hot-loader/react-dom.

I found a interesting thins when i debugger:

  1. Change a lazy load component.
  2. HotLoaderClient will receive a WS msg success.
  3. And react-hot-loader will target update function; The root component forceUpdate()
  4. log warn: React-Hot-Loader: some components were updated out-of-bound. Updating your app to reconcile the changes.
  5. lazy load component re-render
  6. Nothing change in page.

const deepUpdate = () => {
// force flush all updates
runInRenderQueue(() => {
enterHotUpdate();
const gen = getHotGeneration();
module.instances.forEach(inst => inst.forceUpdate());
if (configuration.trackTailUpdates) {
let runLimit = 0;
const checkTailUpdates = () => {
setTimeout(() => {
if (getHotGeneration() !== gen) {
// we know that some components were updated, but not tracking which ones
// even if their updates might be incorporated automatically (like lazy)
// we dont know which one should be tracked, and which updates are important
logger.warn(
'React-Hot-Loader: some components were updated out-of-bound. Updating your app to reconcile the changes.',
);
deepUpdate();
} else if (++runLimit < 5) {
checkTailUpdates();
}
}, 16);
};
checkTailUpdates();
}
});
};

If i wrap lazy load component by hot, `module, everything work well.

There are some question:

  • Should i wrap any component if it will lazy load?
  • And, why didn't update pages after lazy component re-render.

@theKashey theKashey reopened this May 7, 2020
@theKashey
Copy link
Collaborator

Found a problem in tailUpdate - any pure/memo component could stop this "secondary" update. So if your application is good written - you will experience this problem, but only if react-dom patch is not enabled.

I don't have a "broken" example I am able to fix, so, @xyy94813 - could you try to use this version of hot.dev.js, and check is it helping in your case or not - https://github.com/gaearon/react-hot-loader/blob/b14f49b085a6b48b8eeadeeb1a4bf25c981dc71c/src/hot.dev.js

https://github.com/gaearon/react-hot-loader/pull/1448/files#diff-eb1f44974215c23befb11f74f6a2d4d4

@xyy94813
Copy link

xyy94813 commented May 7, 2020

@theKashey

This version work well for me,even i set trackTailUpdates to false.

Is it a excepted?

@xyy94813
Copy link

xyy94813 commented May 7, 2020

@theKashey

Well... Looks like it has side effects

Each child node in the chunk will be re-mounted again.

I'm not sure what is your expectation.

@theKashey
Copy link
Collaborator

theKashey commented May 7, 2020

The changes I've made could not cause remount. They were just about a bit more deeper updates.

@xyy94813
Copy link

xyy94813 commented May 8, 2020

I am stuck in confusion...

I write a minimized implementation...

Everything work well with react-hot-loader@4.12.20...
PS: lazy-component will be re-mount too...

@xuya227939
Copy link

I have also encountered the same problem,How can I solve it, for example?

@X-neuron
Copy link

webpack.dev.config.js:

resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
      "@": path.resolve(__dirname, 'src'),
      // 'react-dom': '@hot-loader/react-dom',  //delete this line
    }
  },
{
            loader: 'babel-loader',
            options: {
              cacheDirectory: true,
              // See #6846 for context on why cacheCompression is disabled
              cacheCompression: false,
              presets: ['@babel/preset-env'],
              plugins: [
                'lodash',
                // 'react-hot-loader/babel',  // delete this line
                // '@babel/plugin-proposal-object-rest-spread',
              ]
            },
          },

in app.jsx : just use export default hot(App);
it will work fine in code spliting condition

@X-neuron
Copy link

I have also encountered the same problem,How can I solve it, for example?

https://github.com/X-neuron/antdFront.git this is good example for hot reload in code split condition

@linshuizhaoying
Copy link

I have also encountered the same problem,How can I solve it, for example?

https://github.com/X-neuron/antdFront.git this is good example for hot reload in code split condition

I can't believe the official configuration caused the error, but it exist...

@xyy94813
Copy link

I am using react-refresh with react-refresh-webpack-plugin.
It work well with lazy-component.

This plugin has been integrated into CRA.
It looks like it will be released with CRA V4.

react-hot-loader will be deprecated...
#1453

@theKashey
Copy link
Collaborator

It's already

@theKashey theKashey mentioned this issue Sep 22, 2020
4 tasks
theKashey added a commit that referenced this issue Sep 22, 2020
* feat: support React 17

* add react 17 tests

* fix: use enzyme 16 adapter for React 17

* fix: add React 17 support for lazy, related to #1425

* ci uses absolute paths

* fix: split trackTailUpdate into two options. Enable lazy wrapping by default

* update tests

* update yarn.lock

* linting

* reverse wrapLazy option effect
@monochrome-yeh
Copy link

I am using react-refresh with react-refresh-webpack-plugin.
It work well with lazy-component.

This plugin has been integrated into CRA.
It looks like it will be released with CRA V4.

react-hot-loader will be deprecated...
#1453

How did you solve this issue,
I’m using cra4.0 (react17.0.1) with react-refresh and we pack plug-in, it still could not be able to handle hot reload with react.lazy component.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants