vite: HMR breaks when modifying React context provider
Describe the bug
Vite HMR breaks when modifying React context provider Related: https://github.com/vitejs/vite-plugin-react/issues/24
Reproduction
System Info
Output of npx envinfo --system --npmPackages vite,@vitejs/plugin-vue --binaries --browsers:
System:
OS: macOS 10.15.7
CPU: (8) x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
Memory: 413.26 MB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 15.14.0 - ~/.nvm/versions/node/v15.14.0/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 7.7.6 - ~/.nvm/versions/node/v15.14.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Browsers:
Brave Browser: 89.1.21.76
Chrome: 90.0.4430.93
Firefox: 87.0
Firefox Developer Edition: 89.0
Safari: 14.0.3
npmPackages:
vite: ^2.2.3 => 2.2.4
Used package manager: npm
Logs
Before submitting the issue, please make sure you do the following
- 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.
- Provide a description in this issue that describes the bug.
- 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: 57
- Comments: 51 (6 by maintainers)
Same issue here, but im trying to be more specific with that.
In my experience:
Running
npm run devworks. Forcing a hot reload on this file, crashes (context gets default value for alluseContextcalls).Running
npm run devworks. Forcing a hot reload on any of those files, still works.Tell me if you need more info, or a minium reproduction repo.
Hope it helps!
I’ve pushed up a PR that fixes this issue, according to a test I wrote based off the reproduction in the issue description. But, it requires a change to how Vite handles
import.meta.hot.invalidate(), so I think it will need some discussion with the Vite team.@selrond Is there a solution to this problem?
Some correction, Vite 3 is out, however Vite 3’s HMR still didn’t support React Context yet.
Your welcome!
Hence I would not recommend react developers using vite as development tool. Hence, u see Nextjs, ionic, and bunch of huge react frameworks still did not using vite yet. Nextjs, Webpack are much more mature for react development, however vite is more focus on vue 3 based on my understanding 👍
Some add on, React Context is great feature, without React context, We cant build a scalable and huge react project with ease!
For those thumb down reaction, please share your thought and tell me am i say something wrong? Please correct me if im wrong, Thanks!
In my case the context mechanism behind react seems to break - I get 2 renders of the same component:
My config for vite is empty so no other plugins can be influencing this. The only thing that helps is restarting vite (simple reload of the website does not work so it must be caching of HMR even on reloads). Disabling HMR entirely
server.hmr = falsefixes the issue at the cost of no HMR.After changing more things afterwards I suddenly started getting a weird
_s is not definedin the component even with the most barebones context when HMR kicks in after changing anything. (again fixed by restarting vite).Debug trace from Vite
$ vite --debug vite:config TS + native esm config loaded in 27ms URL { href: 'file:///home/some-random-app/packages/app/vite.config.ts', origin: 'null', protocol: 'file:', username: '', password: '', host: '', hostname: '', port: '', pathname: '/home/some-random-app/packages/app/vite.config.ts', search: '', searchParams: URLSearchParams {}, hash: '' } +0ms vite:config using resolved config: { vite:config server: { fs: { strict: undefined, allow: [Array] } }, vite:config configFile: '/home/some-random-app/packages/app/vite.config.ts', vite:config configFileDependencies: [ 'vite.config.ts' ], vite:config inlineConfig: { vite:config root: undefined, vite:config base: undefined, vite:config mode: undefined, vite:config configFile: undefined, vite:config logLevel: undefined, vite:config clearScreen: undefined, vite:config server: { fs: [Object] } vite:config }, vite:config root: '/home/some-random-app/packages/app', vite:config base: '/', vite:config resolve: { dedupe: undefined, alias: [ [Object], [Object] ] }, vite:config publicDir: '/home/some-random-app/packages/app/public', vite:config cacheDir: '/home/some-random-app/packages/app/node_modules/.vite', vite:config command: 'serve', vite:config mode: 'development', vite:config isProduction: false, vite:config plugins: [ vite:config 'vite:pre-alias', vite:config 'alias', vite:config 'vite:modulepreload-polyfill', vite:config 'vite:resolve', vite:config 'vite:html', vite:config 'vite:css', vite:config 'vite:esbuild', vite:config 'vite:json', vite:config 'vite:wasm', vite:config 'vite:worker', vite:config 'vite:asset', vite:config 'vite:define', vite:config 'vite:css-post', vite:config 'vite:client-inject', vite:config 'vite:import-analysis' vite:config ], vite:config build: { vite:config target: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ], vite:config polyfillModulePreload: true, vite:config outDir: 'dist', vite:config assetsDir: 'assets', vite:config assetsInlineLimit: 4096, vite:config cssCodeSplit: true, vite:config sourcemap: false, vite:config rollupOptions: {}, vite:config commonjsOptions: { include: [Array], extensions: [Array] }, vite:config dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] }, vite:config minify: 'terser', vite:config terserOptions: {}, vite:config write: true, vite:config emptyOutDir: null, vite:config manifest: false, vite:config lib: false, vite:config ssr: false, vite:config ssrManifest: false, vite:config brotliSize: true, vite:config chunkSizeWarningLimit: 500, vite:config watch: null vite:config }, vite:config env: { vite:config VITE_FUZZ_LOCALES: 'true', vite:config BASE_URL: '/', vite:config MODE: 'development', vite:config DEV: true, vite:config PROD: false vite:config }, vite:config assetsInclude: [Function: assetsInclude], vite:config logger: { vite:config hasWarned: false, vite:config info: [Function: info], vite:config warn: [Function: warn], vite:config warnOnce: [Function: warnOnce], vite:config error: [Function: error], vite:config clearScreen: [Function: clearScreen], vite:config hasErrorLogged: [Function: hasErrorLogged] vite:config }, vite:config createResolver: [Function: createResolver], vite:config optimizeDeps: { esbuildOptions: { keepNames: undefined } } vite:config } +5ms vite:deps Hash is consistent. Skipping. Use --force to override. +0msvite v2.5.1 dev server running at:
ready in 166ms.
vite:time 1ms / +0ms vite:spa-fallback Rewriting GET / to /index.html +0ms vite:time 17ms /index.html +55ms vite:resolve 1ms /@vite/client -> /home/some-random-app/node_modules/vite/dist/client/client.mjs +0ms vite:load 1ms [fs] /@vite/client +0ms vite:resolve 0ms @vite/env -> /home/some-random-app/node_modules/vite/dist/client/env.mjs +9ms vite:transform 6ms /@vite/client +0ms vite:time 13ms /@vite/client +123ms vite:resolve 1ms /src/main.tsx -> /home/some-random-app/packages/app/src/main.tsx +3ms vite:load 1ms [fs] /src/main.tsx +11ms vite:resolve 0ms react -> /home/some-random-app/packages/app/node_modules/.vite/react.js?v=c73c3b06&es-interop +6ms vite:resolve 0ms /node_modules/.vite/react.js?v=c73c3b06&es-interop -> /home/some-random-app/packages/app/node_modules/.vite/react.js?v=c73c3b06&es-interop +0ms vite:resolve 0ms react-dom -> /home/some-random-app/packages/app/node_modules/.vite/react-dom.js?v=c73c3b06&es-interop +3ms vite:resolve 0ms /node_modules/.vite/react-dom.js?v=c73c3b06&es-interop -> /home/some-random-app/packages/app/node_modules/.vite/react-dom.js?v=c73c3b06&es-interop +1ms vite:resolve 2ms app/src/components/organisms -> /home/some-random-app/packages/app/src/components/organisms/index.ts +3ms vite:resolve 0ms /src/components/organisms/index.ts -> /home/some-random-app/packages/app/src/components/organisms/index.ts +0ms vite:resolve 1ms app/src/services/api-client/api-client -> /home/some-random-app/packages/app/src/services/api-client/api-client.ts +1ms vite:resolve 0ms /src/services/api-client/api-client.ts -> /home/some-random-app/packages/app/src/services/api-client/api-client.ts +0ms vite:resolve 0ms app/src/services/users/users -> /home/some-random-app/packages/app/src/services/users/users.ts +0ms vite:resolve 0ms /src/services/users/users.ts -> /home/some-random-app/packages/app/src/services/users/users.ts +0ms vite:resolve 1ms app/src/services/localization/localization -> /home/some-random-app/packages/app/src/services/localization/localization.ts +1ms vite:resolve 0ms /src/services/localization/localization.ts -> /home/some-random-app/packages/app/src/services/localization/localization.ts +0ms vite:resolve 0ms app/src/contexts -> /home/some-random-app/packages/app/src/contexts/index.ts +0ms vite:resolve 0ms /src/contexts/index.ts -> /home/some-random-app/packages/app/src/contexts/index.ts +0ms vite:resolve 0ms /node_modules/.vite/react.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/react.js?v=c73c3b06 +0ms vite:resolve 0ms /node_modules/.vite/react-dom.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/react-dom.js?v=c73c3b06 +1ms vite:transform 15ms /src/main.tsx +18ms vite:time 18ms /src/main.tsx +18ms vite:load 0ms [fs] npm: vite +56ms vite:rewrite 0ms [no imports] /home/some-random-app/node_modules/vite/dist/client/env.mjs +0ms vite:transform 0ms npm: vite +42ms vite:time 2ms npm: vite +41ms vite:load 0ms [fs] /src/components/organisms/index.ts +9ms vite:resolve 0ms ./app/App -> /home/some-random-app/packages/app/src/components/organisms/app/App.tsx +53ms vite:resolve 0ms /src/components/organisms/app/App.tsx -> /home/some-random-app/packages/app/src/components/organisms/app/App.tsx +1ms vite:transform 3ms /src/components/organisms/index.ts +12ms vite:time 5ms /src/components/organisms/index.ts +12ms vite:load 1ms [fs] /src/services/api-client/api-client.ts +6ms vite:resolve 1ms app/src/batteries/server-client/server-client -> /home/some-random-app/packages/app/src/batteries/server-client/server-client.ts +6ms vite:resolve 0ms /src/batteries/server-client/server-client.ts -> /home/some-random-app/packages/app/src/batteries/server-client/server-client.ts +0ms vite:resolve 0ms app/src/batteries/singleton/singleton -> /home/some-random-app/packages/app/src/batteries/singleton/singleton.ts +0ms vite:resolve 1ms /src/batteries/singleton/singleton.ts -> /home/some-random-app/packages/app/src/batteries/singleton/singleton.ts +1ms vite:resolve 0ms app/src/config -> /home/some-random-app/packages/app/src/config.ts +0ms vite:resolve 0ms /src/config.ts -> /home/some-random-app/packages/app/src/config.ts +0ms vite:transform 5ms /src/services/api-client/api-client.ts +7ms vite:time 6ms /src/services/api-client/api-client.ts +7ms vite:load 0ms [fs] /src/services/users/users.ts +7ms vite:resolve 0ms server/src/api/user/route -> /home/some-random-app/packages/server/src/api/user/route.ts +6ms vite:resolve 0ms app/src/batteries/state/state -> /home/some-random-app/packages/app/src/batteries/state/state.ts +1ms vite:resolve 0ms /src/batteries/state/state.ts -> /home/some-random-app/packages/app/src/batteries/state/state.ts +0ms vite:transform 6ms /src/services/users/users.ts +8ms vite:time 7ms /src/services/users/users.ts +8ms vite:load 0ms [fs] /src/services/localization/localization.ts +8ms vite:resolve 1ms i18next -> /home/some-random-app/packages/app/node_modules/.vite/i18next.js?v=c73c3b06 +6ms vite:resolve 0ms /node_modules/.vite/i18next.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/i18next.js?v=c73c3b06 +0ms vite:resolve 0ms react-i18next -> /home/some-random-app/packages/app/node_modules/.vite/react-i18next.js?v=c73c3b06 +0ms vite:resolve 0ms /node_modules/.vite/react-i18next.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/react-i18next.js?v=c73c3b06 +0ms vite:resolve 0ms i18next-icu -> /home/some-random-app/packages/app/node_modules/.vite/i18next-icu.js?v=c73c3b06 +0ms vite:resolve 0ms /node_modules/.vite/i18next-icu.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/i18next-icu.js?v=c73c3b06 +0ms vite:resolve 0ms i18next-http-backend -> /home/some-random-app/packages/app/node_modules/.vite/i18next-http-backend.js?v=c73c3b06 +0ms vite:resolve 0ms /node_modules/.vite/i18next-http-backend.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/i18next-http-backend.js?v=c73c3b06 +1ms vite:resolve 0ms ./fuzzer -> /home/some-random-app/packages/app/src/services/localization/fuzzer.ts +1ms vite:resolve 0ms /src/services/localization/fuzzer.ts -> /home/some-random-app/packages/app/src/services/localization/fuzzer.ts +0ms vite:transform 6ms /src/services/localization/localization.ts +8ms vite:time 7ms /src/services/localization/localization.ts +8ms vite:load 0ms [fs] /src/contexts/index.ts +9ms vite:resolve 0ms ./services/services -> /home/some-random-app/packages/app/src/contexts/services/services.ts +7ms vite:resolve 0ms /src/contexts/services/services.ts -> /home/some-random-app/packages/app/src/contexts/services/services.ts +0ms vite:transform 3ms /src/contexts/index.ts +6ms vite:time 5ms /src/contexts/index.ts +7ms vite:load 0ms [fs] /src/components/organisms/app/App.tsx +9ms vite:resolve 0ms app/src/batteries/style/style -> /home/some-random-app/packages/app/src/batteries/style/style.ts +10ms vite:resolve 1ms /src/batteries/style/style.ts -> /home/some-random-app/packages/app/src/batteries/style/style.ts +1ms vite:resolve 2ms app/src/main -> /home/some-random-app/packages/app/src/main.tsx +2ms vite:resolve 1ms daisyui/dist/full.css -> /home/some-random-app/node_modules/daisyui/dist/full.css +1ms vite:transform 7ms /src/components/organisms/app/App.tsx +14ms vite:time 9ms /src/components/organisms/app/App.tsx +13ms vite:load 1ms [fs] /src/batteries/server-client/server-client.ts +21ms vite:resolve 0ms @trpc/client -> /home/some-random-app/packages/app/node_modules/.vite/@trpc_client.js?v=c73c3b06 +17ms vite:resolve 0ms /node_modules/.vite/@trpc_client.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/@trpc_client.js?v=c73c3b06 +0ms vite:transform 4ms /src/batteries/server-client/server-client.ts +17ms vite:time 6ms /src/batteries/server-client/server-client.ts +18ms vite:load 2ms [fs] /src/config.ts +8ms vite:load 1ms [fs] /src/batteries/singleton/singleton.ts +0ms vite:transform 1ms /src/config.ts +5ms vite:time 3ms /src/config.ts +4ms vite:rewrite 0ms [no imports] src/batteries/singleton/singleton.ts +81ms vite:transform 5ms /src/batteries/singleton/singleton.ts +4ms vite:time 7ms /src/batteries/singleton/singleton.ts +4ms vite:load 1ms [fs] …/server/src/api/user/route.ts +16ms vite:load 1ms [fs] /src/batteries/state/state.ts +0ms vite:resolve 1ms server/src/routes -> /home/some-random-app/packages/server/src/routes.ts +24ms vite:transform 4ms …/server/src/api/user/route.ts +15ms vite:time 6ms …/server/src/api/user/route.ts +15ms vite:resolve 0ms meiosis-setup/immer -> /home/some-random-app/packages/app/node_modules/.vite/meiosis-setup_immer.js?v=c73c3b06 +1ms vite:resolve 0ms /node_modules/.vite/meiosis-setup_immer.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/meiosis-setup_immer.js?v=c73c3b06 +0ms vite:resolve 0ms meiosis-setup/simple-stream -> /home/some-random-app/packages/app/node_modules/.vite/meiosis-setup_simple-stream.js?v=c73c3b06 +0ms vite:resolve 0ms /node_modules/.vite/meiosis-setup_simple-stream.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/meiosis-setup_simple-stream.js?v=c73c3b06 +0ms vite:resolve 0ms immer -> /home/some-random-app/packages/app/node_modules/.vite/immer.js?v=c73c3b06 +0ms vite:resolve 0ms /node_modules/.vite/immer.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/immer.js?v=c73c3b06 +1ms vite:transform 5ms /src/batteries/state/state.ts +2ms vite:time 7ms /src/batteries/state/state.ts +2ms vite:load 0ms [fs] /src/contexts/services/services.ts +32ms vite:load 0ms [fs] /src/batteries/style/style.ts +2ms vite:resolve 0ms nanoid/non-secure -> /home/some-random-app/packages/app/node_modules/.vite/nanoid_non-secure.js?v=c73c3b06 +31ms vite:resolve 0ms /node_modules/.vite/nanoid_non-secure.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/nanoid_non-secure.js?v=c73c3b06 +0ms vite:transform 5ms /src/contexts/services/services.ts +31ms vite:time 6ms /src/contexts/services/services.ts +31ms vite:resolve 0ms twind/css -> /home/some-random-app/packages/app/node_modules/.vite/twind_css.js?v=c73c3b06 +2ms vite:resolve 1ms /node_modules/.vite/twind_css.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/twind_css.js?v=c73c3b06 +1ms vite:transform 5ms /src/batteries/style/style.ts +3ms vite:time 7ms /src/batteries/style/style.ts +3ms vite:load 3ms [fs] npm: daisyui +8ms vite:load 1ms [fs] …/server/src/routes.ts +8ms vite:hmr [self-accepts] /home/some-random-app/node_modules/daisyui/dist/full.css +0ms vite:transform 407ms npm: daisyui +412ms vite:time 416ms npm: daisyui +414ms vite:rewrite 1ms [no imports] /home/some-random-app/packages/server/src/routes.ts +466ms vite:transform 405ms …/server/src/routes.ts +3ms vite:time 408ms …/server/src/routes.ts +2ms vite:resolve 0ms /node_modules/.vite/chunk-IHTDASF6.js -> /home/some-random-app/packages/app/node_modules/.vite/chunk-IHTDASF6.js +497ms vite:time 3ms /node_modules/.vite/chunk-IHTDASF6.js.map +84ms vite:load 1ms [fs] /src/services/localization/fuzzer.ts +541ms vite:resolve 0ms pseudo-localization -> /home/some-random-app/packages/app/node_modules/.vite/pseudo-localization.js?v=c73c3b06&es-interop +56ms vite:resolve 0ms /node_modules/.vite/pseudo-localization.js?v=c73c3b06&es-interop -> /home/some-random-app/packages/app/node_modules/.vite/pseudo-localization.js?v=c73c3b06&es-interop +0ms vite:resolve 0ms /node_modules/.vite/pseudo-localization.js?v=c73c3b06 -> /home/some-random-app/packages/app/node_modules/.vite/pseudo-localization.js?v=c73c3b06 +1ms vite:transform 4ms /src/services/localization/fuzzer.ts +140ms vite:time 5ms /src/services/localization/fuzzer.ts +55ms vite:time 1ms /src/locales/en/common.json +165ms vite:hmr [file change] src/main.tsx +22s
THIS IS WHERE I ADD A SINGLE COMMA TO main.tsx AND SAVE - NOW CONTEXT IS FIRING TWICE WITH THE ABOVE PROBLEM
8:52:02 PM [vite] page reload src/main.tsx vite:spa-fallback Rewriting GET / to /index.html +22s vite:time 6ms /index.html +21s vite:cache [304] /@vite/client +0ms vite:time 1ms /@vite/client +46ms vite:load 0ms [fs] /src/main.tsx +22s vite:transform 6ms /src/main.tsx +22s vite:time 7ms /src/main.tsx +8ms vite:cache [304] npm: vite +79ms vite:time 0ms npm: vite +71ms vite:cache [304] /src/services/api-client/api-client.ts +9ms vite:time 0ms /src/services/api-client/api-client.ts +9ms vite:cache [304] /src/services/users/users.ts +1ms vite:time 0ms /src/services/users/users.ts +1ms vite:load 1ms [fs] /src/components/organisms/index.ts +88ms vite:transform 2ms /src/components/organisms/index.ts +84ms vite:time 5ms /src/components/organisms/index.ts +3ms vite:cache [304] /src/services/localization/localization.ts +5ms vite:time 1ms /src/services/localization/localization.ts +3ms vite:cache [304] /src/contexts/index.ts +2ms vite:time 1ms /src/contexts/index.ts +1ms vite:cache [304] /src/batteries/server-client/server-client.ts +14ms vite:time 1ms /src/batteries/server-client/server-client.ts +14ms vite:cache [304] /src/batteries/singleton/singleton.ts +16ms vite:time 1ms /src/batteries/singleton/singleton.ts +16ms vite:cache [304] /src/config.ts +0ms vite:time 1ms /src/config.ts +1ms vite:cache [304] …/server/src/api/user/route.ts +3ms vite:time 1ms …/server/src/api/user/route.ts +2ms vite:cache [304] /src/batteries/state/state.ts +17ms vite:time 1ms /src/batteries/state/state.ts +17ms vite:load 1ms [fs] /src/components/organisms/app/App.tsx +58ms vite:transform 3ms /src/components/organisms/app/App.tsx +58ms vite:time 5ms /src/components/organisms/app/App.tsx +5ms vite:cache [304] /src/contexts/services/services.ts +28ms vite:time 1ms /src/contexts/services/services.ts +24ms vite:cache [304] …/server/src/routes.ts +6ms vite:time 0ms …/server/src/routes.ts +5ms vite:cache [304] /src/batteries/style/style.ts +12ms vite:time 0ms /src/batteries/style/style.ts +12ms vite:cache [memory] /src/main.tsx +0ms vite:time 0ms /src/main.tsx +1ms vite:cache [304] npm: daisyui +6ms vite:time 1ms npm: daisyui +5ms vite:time 2ms /node_modules/.vite/chunk-IHTDASF6.js.map +126ms vite:cache [304] /src/services/localization/fuzzer.ts +213ms vite:time 0ms /src/services/localization/fuzzer.ts +87ms vite:time 0ms /src/locales/en/common.json +62ms
Stacktraces of the 2 context calls done in the component
console.log(useContext(...))I’ve traced down the problem to defining the context in the same file where I called
ReactDOM.render. Since I defined the context here I also export it (to be able to consume it in other components). Since this is the place I call the final render though it’s also the place I import those components which creates a cyclic dependency.The problem then is either the cyclicity and HMR breaking it. Or HMR doing something to the compiled code which creates the context twice which then causes a whole bunch of errors and weird behaviour.
Either way, don’t define context’s in the same file as you call
ReactDOM.renderkids #TILThanks, now I know what’s going on.
DON’T define the context with its provider in the SAME FILE.
HMR will break if any change happen in that file, or any file that is used in the context or the provider.
More about it.
If we have one file with this code:
Any change here, HMR will break.
But separate them into two files:
and
In this way, the issue is resolved, and changes can happen safely everywhere.
I will test it next with a simple mobx store and see what happens.
Update:
After adding a small mobx store, I can confirm, this issue only happens when both context and provider are defined in the same file. Now we need to know, why?
@justinbhopper It works so smooth with no issues. HMR don’t break the provider anymore.
Here’s the steps:
1- create a new vite react ts project. 2- inside App.tsx, add this code:
3- Inside vite.config.ts, add this plugin:
And it works.
Now we just need some better regex matching rules.
Update 1:
Tried this with context in a separated file, it doesn’t work.
To workaround, add this plugin:
and then, wrap
export const CountContext = React.createContext()with__preserveRef()likeexport const CountContext = __preserveRef('CountContext', React.createContext());.stackblitz example
I noticed the 54 likes, the 47 comments, a few duplicate issues, and the implementation of
fastRefreshproperty in the configuration, so the issue can have a workaround.The issue doesn’t feel it deserves the
p3-minor-bug 🔨label.I’m also stuck with issue related to Context and HMR/fast refresh. In my case
createContextandProviderare in separated files. If I modify a component withuseContext, HMR reloads my component but I get an error which means thatuseContextreturn default value (the value increateContext:export const MyContext = createContext({ a: "foo"})) but I need value fromProvider(<MyContext.Provider value={b: "bar"}>)To workaround this issue, I just use
{ fastRefresh: false }option in@vitejs/plugin-reactwhich is clearly disappointing when you are used{ fastRefresh: true }😉It’s still a strong reason to choose nextjs instead of vitejs just because of context losing, in real app, a context losing will easily cause a tab 100% CPU because of an error loop, have to keep a task manager open and kill the tab.
Just ran into this issue on a non-vite project. We are introducing context for the first time into our app. After messing around I finally found that yes moving the createContext call to another file resolves the issue mostly. Editing that file still causes the problem.
@seeker-3 I believe you could use the HMR API to achieve the same: https://vitejs.dev/guide/api-hmr.html#hot-decline
Vite 3 is out, but React context still do not support HMR
I tried the 2nd option, though it does work with HMR. We kind-a lose the capability of Fast Refresh. While fast refresh is still buggy, I think disabling it for now is the only workaround ☹️: https://github.com/vitejs/vite/issues/3301#issuecomment-1080292430
FYI, we stumbled over this problem too, and are using a (somewhat hacky) solution that seems to work, without needing to write Vite plugins or fiddling with HMR API.
The trick is to move the “createContext” call into the provider component. Using a React ref ensures uniqueness.
What do you think? Does this solution have any downsides I am not aware of (except that this has to be repeated for every context, and goes into production code)?
@adnanalbeda I also cannot reproduce the bug using the original repo (https://github.com/selrond/vite-react-usecontext) after upgrading it to
vite@3.0.2and@vitejs/plugin-react@2.0.0. Is this bug still occurring in latest?https://stackblitz.com/edit/github-6861mq-hcsekc
thats not hot reload man haha
reference: https://www.geeksforgeeks.org/difference-between-hot-reloading-and-live-reloading-in-react-native/
same issue here, export useContext will be break when hot reload… feeling weird, and im still trying figure out the solution…
i tried this, wont work… I still had to manually refresh everytime when i save work on my vite project tho.
Could anyone tell me which old version did not have this problem, i wish to downgrade temporary to continue work with my project smoothly…
@sodatea can we mark it as major bug?
I found an temporary solution which is downgrade the vite version to v2.5.0 and use
@vitejs/plugin-react-refreshinstead of@vitejs/plugin-reactshould works without the Tony’s bug.