react-pdf
react-pdf copied to clipboard
Library conflicts with libraries that uses `useSyncExternalStore` React 18 API
Describe the bug
I tried to add @react-pdf/renderer
library to my project that uses import "@preact/signals-react"
and received the next error:
dispatcher.useSyncExternalStore is not a function
To Reproduce
- Generate react project with CRA or VITE
- Add
@react-pdf/renderer
and@preact/signals-react
dependencies - Add next code
- Observe error
import "@preact/signals-react";
import { createRoot } from "react-dom/client";
import { PDFViewer, Document, View, Text, Page } from "@react-pdf/renderer";
function SeparateComponent() {
return <Text>Hello, World!</Text>;
}
createRoot(document.getElementById("root")).render(
<PDFViewer>
<Document>
<Page>
<View>
<Text>Hello, World!</Text>
{/* if you comment next line everything will work properly */}
<SeparateComponent />
</View>
</Page>
</Document>
</PDFViewer>
);
Link to codesandbox: https://codesandbox.io/s/heuristic-worker-o55gp4?file=/src/index.js:0-542
Expected behavior Should work properly
UPDATE: I was able to solve this problem from my side. My actions:
- downgrade library version to @react-pdf/[email protected]
- override library dependencies with npm overrides feature to latest verion:
"overrides": {
"@react-pdf/renderer": {
"react-reconciler": "$react-reconciler",
"scheduler": "$scheduler",
"react": "$react"
}
}
- polyfill 'events' module
It still displays an error in the browser console but the PDF view itself works.
@maxsbelt I tried your approach but somehow it did not solve my issue.
TypeError: dispatcher.useSyncExternalStore is not a function
The overrides you posted cannot resolve $scheduler
and $react-reconciler
so I tried it with latest
.
...
"dependencies": {
"@datadog/browser-logs": "^4.19.1",
"@next-auth/prisma-adapter": "^1.0.5",
"@prisma/client": "^4.11.0",
"@react-pdf/renderer": "^3.1.9",
"@reduxjs/toolkit": "^1.9.3",
"aws-sdk": "^2.1344.0",
"axios": "^1.3.4",
"base64-stream": "^1.0.0",
"bcrypt": "^5.0.0",
"busboy": "^1.6.0",
"concat-stream": "^2.0.0",
"crypto": "^1.0.1",
"crypto-browserify": "^3.12.0",
"date-fns": "^2.29.3",
"dotenv": "^16.0.3",
"events-polyfill": "^2.1.2",
"file-saver": "^2.0.5",
"formik": "^2.2.9",
"hat": "^0.0.3",
"lodash.pick": "^4.4.0",
"lodash.tostring": "^4.1.4",
"mailersend": "^2.0.5",
"md5": "^2.3.0",
"moment": "^2.29.4",
"multiparty": "^4.2.3",
"next": "^13.2.4",
"next-auth": "^4.20.1",
"next-connect": "^0.13.0",
"next-dark-mode": "^3.0.0",
"next-i18next": "^12.0.0",
"next-plausible": "^3.7.2",
"nodemailer": "^6.9.1",
"qrcode.react": "^3.1.0",
"rc-tree": "^5.7.3",
"react": "^18.2.0",
"react-calendly": "^4.1.1",
"react-color": "^2.19.3",
"react-csv": "^2.2.2",
"react-csv-reader": "^4.0.0",
"react-currency-format": "github:mohitgupta8888/react-currency-format#4f365ec5005e23451a3b95da1a209b0025622b8d",
"react-datepicker": "^4.10.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.2.0",
"react-hot-keys": "^2.7.2",
"react-hot-toast": "^2.4.0",
"react-icons": "^4.8.0",
"react-player": "^2.12.0",
"react-redux": "^8.0.5",
"react-semantic-ui-datepickers": "^2.17.2",
"react-sortablejs": "^6.1.4",
"react-transition-group": "^4.4.5",
"recharts": "^2.5.0",
"semantic-ui-css": "^2.5.0",
"semantic-ui-react": "^2.1.4",
"sortablejs": "^1.15.0",
"ua-parser-js": "^1.0.34",
"uuid": "^9.0.0",
"yup": "^1.0.2",
"zxcvbn": "^4.4.2"
},
"devDependencies": {
"@next/bundle-analyzer": "^13.2.4",
"@playwright/test": "^1.32.1",
"@types/bcrypt": "^5.0.0",
"@types/file-saver": "^2.0.5",
"@types/lodash.tostring": "^4.1.7",
"@types/node": "^18.15.10",
"@types/nodemailer": "^6.4.7",
"@types/react": "^18.0.30",
"@types/react-color": "^3.0.6",
"@types/react-csv": "^1.1.3",
"@types/react-currency-format": "^1.0.0",
"@types/react-datepicker": "^4.10.0",
"@types/react-dom": "^18.0.11",
"@types/react-transition-group": "^4.4.5",
"@types/recharts": "^1.8.24",
"@types/sortablejs": "^1.15.1",
"@types/ua-parser-js": "^0.7.36",
"@types/zxcvbn": "^4.4.1",
"@typescript-eslint/eslint-plugin": "^5.57.0",
"@typescript-eslint/parser": "^5.57.0",
"cz-conventional-changelog": "^3.3.0",
"dotenv-cli": "^7.1.0",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-formatter-git-log": "^0.6.4",
"eslint-formatter-mo": "^1.2.0",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-security": "^1.7.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-sonarjs": "^0.19.0",
"eslint-plugin-unicorn": "^46.0.0",
"file-loader": "^6.2.0",
"husky": "^8.0.3",
"lint-staged": "^13.2.0",
"prettier": "^2.8.7",
"prisma": "^4.11.0",
"standard-version": "^9.5.0",
"stylelint": "^13.0.0",
"stylelint-config-idiomatic-order": "^9.0.0",
"stylelint-config-prettier": "^9.0.5",
"stylelint-config-sass-guidelines": "^8.0.0",
"stylelint-config-standard": "^22.0.0",
"stylelint-prettier": "^1.2.0",
"stylelint-scss": "^3.21.0",
"typescript": "^5.0.2",
"url-loader": "^4.1.1",
"webpack": "^5.76.3"
},
"overrides": {
"@react-pdf/renderer": {
"react": "$react",
"react-reconciler": "latest",
"scheduler": "latest"
}
}
Do you maybe have a hint how else to solve it? :)
Here is the full error:
TypeError: dispatcher.useSyncExternalStore is not a function
index.tsx?32c0:114 Uncaught (in promise) TypeError: dispatcher.useSyncExternalStore is not a function
at Object.useSyncExternalStore (react.development.js?1b7e:1676:1)
at LoadableComponent (loadable.js?5107:86:38)
at Jd (react-pdf.browser.es.js?3b48:1113:1)
at qe (react-pdf.browser.es.js?3b48:1571:1)
at ig (react-pdf.browser.es.js?3b48:3435:1)
at hg (react-pdf.browser.es.js?3b48:2829:1)
at bg (react-pdf.browser.es.js?3b48:2823:23)
at Of (react-pdf.browser.es.js?3b48:2625:1)
at eval (react-pdf.browser.es.js?3b48:472:1)
at unstable_runWithPriority (scheduler.development.js?bcd2:818:1)
at hc (react-pdf.browser.es.js?3b48:445:1)
at kc (react-pdf.browser.es.js?3b48:469:1)
at F (react-pdf.browser.es.js?3b48:461:1)
at Wc (react-pdf.browser.es.js?3b48:2461:1)
at Object.updateContainer (react-pdf.browser.es.js?3b48:3747:1)
at updateContainer (react-pdf.browser.es.js?3b48:4069:1)
at pdf (react-pdf.browser.es.js?3b48:4071:1)
at downloadPdf (index.tsx?32c0:112:27)
at Object.onClick (index.tsx?32c0:264:42)
at apply (_apply.js?c902:15:1)
at baseInvoke (_baseInvoke.js?9e4e:21:42)
at apply (_apply.js?c902:16:1)
at eval (_overRest.js?bb93:32:17)
at Button._this.handleClick (Button.js?7a7c:63:14)
at HTMLUnknownElement.callCallback (react-dom.development.js?ac89:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js?ac89:4213:1)
at invokeGuardedCallback (react-dom.development.js?ac89:4277:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js?ac89:4291:1)
at executeDispatch (react-dom.development.js?ac89:9041:1)
at processDispatchQueueItemsInOrder (react-dom.development.js?ac89:9073:1)
at processDispatchQueue (react-dom.development.js?ac89:9086:1)
at dispatchEventsForPlugins (react-dom.development.js?ac89:9097:1)
at eval (react-dom.development.js?ac89:9288:1)
at batchedUpdates$1 (react-dom.development.js?ac89:26140:1)
at batchedUpdates (react-dom.development.js?ac89:3991:1)
at dispatchEventForPluginEventSystem (react-dom.development.js?ac89:9287:1)
at dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay (react-dom.development.js?ac89:6465:1)
at dispatchEvent (react-dom.development.js?ac89:6457:1)
at dispatchDiscreteEvent (react-dom.development.js?ac89:6430:1)
It was actually the suspense loading issue.
I was using next/dynamic
to dynamically load the PDF document component. Directly importing it solved the issue together with your overrides solution :)
It hit me while reading this: https://github.com/reduxjs/react-redux/issues/1977
I am having the same issue. I am using Zustand to create a store and attempting to access this store inside my React PDF components to dynamic render its contents.
My solution for this was to access the Zustand store in the component that renders PDFViewer
and pass the needed values to the component that renders Document
as props. If the PDF is too complex, it might be helpful to create a context
I was using react-redux and NextJS. I had to downgrade to version ^7.0.0 (npm i react-redux@^7.0.0).
I had the same error when trying nextjs dynamic import too. PDF is huge