pqina / react-filepond

🔌 A handy FilePond adapter component for React
https://pqina.nl/filepond
MIT License
1.84k stars 90 forks source link

[Bug]: <StrictMode> throws error when used with React 18 #207

Open hug-0 opened 2 years ago

hug-0 commented 2 years ago

Is there an existing issue for this?

Have you updated React FilePond, FilePond, and all plugins?

Describe the bug

Hi there,

First off - thanks for an amazing file uploader! It's rare to find a feature-rich package with top notch UX out of the box.

After upgrading to React 18 and the new createRoot(...) syntax, I am no longer able to load react-filepond. The following error messages are logged:

TypeError
null is not an object (evaluating 'referenceNode.parentNode.insertBefore')
(anonymous function)
[https://codesandbox.io/static/js/vendors~react-devtools-backend.759c29504.chunk.js:1:230840]()
u
[https://codesandbox.io/static/js/vendors~react-devtools-backend.759c29504.chunk.js:1:230954]()
n
[https://codesandbox.io/static/js/vendors~react-devtools-backend.759c29504.chunk.js:1:229900]()
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error.
This error overlay is powered by `react-error-overlay` used in `create-react-app`.

There also seems to be a typing issue with Typescript for onupdatefiles(...). I get the following issue:

Type 'Dispatch<SetStateAction<never[]>>' is not assignable to type '(files: FilePondFile[]) => void'.

I'm not sure if the two are related. I can clearly see that the class FilePondFile is exported from the library, but Typescript is complaining about the types from the getting started example. Specifying the type in useState<> doesn't work, because typescript can't find any exported member for FilePondFile that's requested by the typechecker.

Any help figuring this out is greatly appreciated!

Thanks, H

Reproduction

Please check out this codesandbox I created to reproduce the issue. All of the specific versions used are detailed there.

Link to sandbox.

Environment

- Device: Macbook Pro, 16 inch (2020)
- OS: MacOS Monterey 12.3.1
- Browser: Chrome, Safari, Firefox
- React version: 18.0
rikschennink commented 2 years ago

Hey! Thanks! And thanks for the detailed issue report, going to take a look at this later this week and will get back to you.

rikschennink commented 2 years ago

I've locally updated the example project to React 18, it worked fine until I wrapped the <App /> win <StrictMode>

Not sure, maybe React is not happy that FilePond uses classic DOM APIs to interact with its child elements?

I've adjusted the example a bit so the TypeScript error is gone. There's probably better ways to approach that, but this works.

https://codesandbox.io/s/react-filepond-issues-forked-0zg5st?file=/src/App.tsx

hug-0 commented 2 years ago

Thanks.

I'm still stumped. I also removed StrictMode and my sandbox now runs. But my actual project environment still throws the same error. I'm not using StrictMode there either.

React-FilePond runs well in React 17 in my project, but not at all in React 18.

Any suggestions on what I might go looking for to uncover the actual issue?

The log is

filepond.js:1457 Uncaught TypeError: Cannot read properties of null (reading 'insertBefore')
    at insertBefore (filepond.js:1457:1)
    at Object.replaceElement (filepond.js:12086:1)
    at createAppAtElement (filepond.js:12341:1)
    at createApp (filepond.js:12349:1)
    at create (filepond.js:12620:1)
    at FilePond.componentDidMount (react-filepond.js:85:1)
    at invokeLayoutEffectMountInDEV (react-dom.development.js:24926:1)
    at invokeEffectsInDev (react-dom.development.js:27142:1)
    at commitDoubleInvokeEffectsInDEV (react-dom.development.js:27118:1)
    at commitRootImpl (react-dom.development.js:26705:1)

EDIT: As a sidebar, I only get this issue in development mode. In my production build, filepond still works as expected.

rikschennink commented 2 years ago

Maybe you have <StrictMode> wrapping a node at some other location in your code?

About the error, for some reason the parentNode of FilePonds root element is null for a short moment. Not sure why.

hug-0 commented 2 years ago

@rikschennink - Yes, you're right. I had missed a StrictMode wrapper in an enveloping container. Thanks!

It's quite nice to be able to run StrictMode in development, as the errors are a lot more meaningful than without them, as per the React docs. I'll disable it for now!

Let me know if there're any additional digging you'd like help with.

Cheers, H

rikschennink commented 2 years ago

Okay, glad to hear that.

I'll investigate further when I have some more time.

Hoped there was a way to disable strict mode for a part of the subtree but that is not possible as it would undermine the reason for having strict mode, which makes sense. https://github.com/facebook/react/issues/16362

KentShikama commented 2 years ago

@rikschennink It looks like destroy isn't called after the first render and so when strict mode goes for its second render it isn't starting from a clean slate.

rikschennink commented 2 years ago

Should be fixed in 7.1.2

caribouflex commented 1 year ago

Just got the same issue recently and 7.1.2 fixed it. Thank you 🙏

gual commented 6 months ago

Any idea on how to fix the other half of this issue? I'm also getting the Type 'Dispatch<SetStateAction<never[]>>' is not assignable to type '(files: FilePondFile[]) => void'. error with React 18.

magixus commented 3 weeks ago

@gual you can use @rikschennink solution

<FilePond
...
 onupdatefiles={setFiles as (files: FilePondFile[]) => void}
...
/>