vite: the vite's HMR does not work when I use React.lazy() API for lazyload
Describe the bug
when I use React.lazy(),like this:
// router/index.ts
import React from 'react';
const Home = React.lazy(() => import('../views/Home'));
const About = React.lazy(() => import('../views/About'));
const routes = [
{
path: '/',
exact: true,
component: Home
},
{
path: '/about',
exact: true,
component: About
},
{
path: '/login',
exact: true,
component: React.lazy(() => import('../views/login/login'))
},
{
path: '/form-page',
exact: true,
component: React.lazy(() => import('../views/form-test/form-page'))
},
{
path: '/props-up',
exact: true,
component: React.lazy(() => import('../views/form-test/props-up'))
}
];
export default routes;
supplement!I use react-router-config
manage my routes information,like this:
// App.tsx
import { renderRoutes } from 'react-router-config';
import routes from '@/router';
// other code
render(): JSX.Element {
return (
<Router>
<div className={styles.container}>
<div className={styles['title-wraper']}>
<Link to="/">
<span className={styles['link-title']}>Home</span>
</Link>
<span className={styles['link-line']}> | </span>
<Link to="/about">
<span className={styles['link-title']}>About</span>
</Link>
</div>
<Switch>
<React.Suspense fallback={<Loading></Loading>}>
{renderRoutes(routes)}
</React.Suspense>
</Switch>
</div>
</Router>
);
}
when I modify some code in Home.tsx or About.tsx etc,the HMR was not effected.I need refresh the broswer can see my modification.
if I dont use React.lazy() API,the HMR is normal!
Reproduction
I see vite HMR can work,but it nonitor a wrong file.
I modify About.tsx,but vite HMR feed back router/index.ts.
System Info
- OS: win 10
- browser:Chrome 91
- react(react-dom): 17.0.2
- react-router-dom: 5.2.0
- react-router-config: 5.1.1
- vite: 2.4.2
vite.config.ts
import path from 'path';
import { defineConfig } from 'vite';
import reactRefresh from '@vitejs/plugin-react-refresh';
import eslintPlugin from 'vite-plugin-eslint';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [reactRefresh(), eslintPlugin()],
resolve: {
alias: { '@': path.join(__dirname, 'src') }
},
css: {
modules: {
generateScopedName: '[name]__[local]--[hash:base64:5]'
}
}
});
### Used Package Manager
npm
### Logs
```shell
no error!
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn’t already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue. For example, if it’s a Vue SFC related bug, it should likely be reported to https://github.com/vuejs/vue-next instead.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 4
- Comments: 22 (4 by maintainers)
damn.
It looks like if you give function component a name, then both c-r-a and vite example works.So, It’s definitely not a bug of vite, but an intentional behavior of react facebook/react#21181.
@guibwl After i used
@loadable/component
, it works fine。ThankSame issue, My App is like below code:
After use React.lazy, change in Component A (or B) cannot hot reload, but need switch routing.
I’m encountering this issue and can’t find any obvious places where i’m not defining a component as a const before export defaulting it.
Any additional input on how people got over this would be appreciated!
I see… Well, my setup is a bit more complex with routing, custom providers and hooks. In a nutshell, when HMR is triggered for a component in the lazy loaded path, a hook fails to get a parameter from the URL. It just returns a default value I’ve set without actually checking the URL again.
If I find the time, I’ll try making a small reproduction.
I think using
Foo
works because component names have to start with a capital letter: https://reactjs.org/docs/components-and-props.htmlhttps://github.com/iheyunfei/vite-bug-report-4298 I create a reproduction repo. I both using create-react-app and vite to reproduce the problem successfully. So, I guess this is the problem of upstream
react-refresh
, not vite.And the problem only happens on function component, Class Component seems to work.
I’m using
@loadable/component
and Function components its worked fine for me.