parcel icon indicating copy to clipboard operation
parcel copied to clipboard

HMR crashes page with React when saving Provider Component

Open iFreilicht opened this issue 2 years ago • 1 comments

🐛 bug report

When I save a file in my project (even if it wasn't changed) that provides a Context and the respective Provider, HMR will try to hot-reload the page and crash it in the process.

The error message is TypeError: _reactDefault.default.useContext(...) is undefined.

image

🎛 Configuration (.babelrc, package.json, cli command)

No babel, I just run

npm exec parcel public/index.html

🤔 Expected Behavior

I would expect the hot reload to work.

😯 Current Behavior

The page crashes with the following error:

TypeError: _reactDefault.default.useContext(...) is undefined
ToastPlayground
src/components/ToastPlayground/ToastPlayground.js:9:29

   6 | import { ToastContext } from "../ToastProvider/ToastProvider";
   7 | 
   8 | function ToastPlayground() {
>  9 |   const { addToast } = React.useContext(ToastContext);
     |                             ^  10 | 
  11 |   return (
  12 |     <div className={styles.wrapper}>

renderWithHooks
node_modules/react-dom/cjs/react-dom.development.js:16305:27
mountIndeterminateComponent
node_modules/react-dom/cjs/react-dom.development.js:20074:12
beginWork
node_modules/react-dom/cjs/react-dom.development.js:21587:15
callCallback
node_modules/react-dom/cjs/react-dom.development.js:4164:13
invokeGuardedCallbackDev
node_modules/react-dom/cjs/react-dom.development.js:4213:15
invokeGuardedCallback
node_modules/react-dom/cjs/react-dom.development.js:4277:30
beginWork$1
node_modules/react-dom/cjs/react-dom.development.js:27451:28
performUnitOfWork
node_modules/react-dom/cjs/react-dom.development.js:26557:11
workLoopSync
node_modules/react-dom/cjs/react-dom.development.js:26466:22
renderRootSync
node_modules/react-dom/cjs/react-dom.development.js:26434:6
performSyncWorkOnRoot
node_modules/react-dom/cjs/react-dom.development.js:26085:34
flushSyncCallbacks
node_modules/react-dom/cjs/react-dom.development.js:12042:21
flushSync
node_modules/react-dom/cjs/react-dom.development.js:26201:6
scheduleRefresh
node_modules/react-dom/cjs/react-dom.development.js:27795:14
.hdge7</performReactRefresh/<
node_modules/react-refresh/cjs/react-refresh-runtime.development.js:300:16
performReactRefresh
node_modules/react-refresh/cjs/react-refresh-runtime.development.js:289:25
.km3Ru</enqueueUpdate<
node_modules/@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js:33:10
.km3Ru</debounce/<
node_modules/@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js:20:13
.km3Ru</module.exports.postlude/<
node_modules/@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js:81:8
.icZzK</hmrAccept/<
node_modules/@parcel/runtime-browser-hmr/lib/runtime-3a0660f0e3b450ae.js:484:34
hmrAccept
node_modules/@parcel/runtime-browser-hmr/lib/runtime-3a0660f0e3b450ae.js:483:32
.icZzK</ws.onmessage
node_modules/@parcel/runtime-browser-hmr/lib/runtime-3a0660f0e3b450ae.js:147:22

💁 Possible Solution

If only I knew 🤷

🔦 Context

I wanted to create a Provider component to avoid prop drilling as part of an exercise.

💻 Code Sample

See https://github.com/iFreilicht/project-toast/tree/parcel-hmr-repro. To quote the README:

To reproduce the issue, run

npm install
npm run dev

The server will start at http://localhost:1234/. Open that page.

Then, run

touch src/components/ToastProvider/ToastProvider.js

This will crash the page.

🌍 Your Environment

Software Version(s)
Parcel 2.10.3
Node 20.4.0
npm/Yarn npm 9.7.2
Operating System macOS 14.1.1

iFreilicht avatar Nov 22 '23 22:11 iFreilicht

Same with me it, it can break anything. I got an issue with 'react' is not found. Also, HMR does not work when you use useContext.

image image image Modify any code anywhere in the source code, the page refreshes. HMR does not work. Also states get reset. tried preserving the logs. it crashes the code.

k1941996 avatar Dec 14 '23 10:12 k1941996

This is still broken.

iFreilicht avatar Dec 09 '24 06:12 iFreilicht

I'm seeing the same behavior on the same project as the OP, but 100% of the time. npm run dev will report the undefined value from useContext(): Screenshot 2025-01-03 at 3 01 37 PM

Assigning the values returned from createContext() and from useContext() to global variables shows they are different: Screenshot 2025-01-03 at 3 02 51 PM https://react.dev/reference/react/useContext#my-component-doesnt-see-the-value-from-my-provider

Here's a branch running parcel and React 19 where you can reproduce: https://github.com/figureone/project-toast/tree/broken-parcel-usecontext

figureone avatar Jan 04 '25 01:01 figureone

Never mind, I'm a dummy and messed up my imports. For reference, the broken useContext() in the comment above was caused because the ToastContext import was pulling the default export instead of a named export, causing the issues. Simple fix is here: https://github.com/figureone/project-toast/commit/6d118ca3916f775d5ecd8faa280d288dc4b17f2b

There may still be issues from OP's report, but my problem is solved by the above.

figureone avatar Jan 06 '25 19:01 figureone