react-filepond
react-filepond copied to clipboard
Flash of unstyled content (FOUC)
Summary
The react-filepond
component has a flash of unstyled content for me when it first comes up. This happens when I'm using React server-side rendering. It's happened for me when using both Gatsby.js and Next.js.
Here's a recording of me refreshing the page to show it:
How to reproduce
Just use the Filepond
component in a SSR-ed app. I'm using it exactly like the example in this repo does. Here's a simplified version of my component:
import * as React from "react";
import "filepond/dist/filepond.min.css";
import { FilePond } from "react-filepond";
export default class MyComponent extends React.PureComponent {
render() {
return (
<div>
<FilePond allowMultiple={false}
onprocessfile={this.onProcessFile}
onprocessfilestart={this.onProcessFileStart}
beforeAddFile={this.beforeAddFile}
server={{
process: {
url: "/api/scratchpad/from_file",
method: "POST",
withCredentials: true,
headers: {},
onload: this.onLoad,
onerror: this.onError,
ondata: this.onData
}
}} />
</div>
);
}
}
Expected behaviour
It should have the styled loaded before rendering the component so that there isn't a flicker.
Additional information
Environment | Version |
---|---|
OS | Linux |
Device | Laptop |
Browser | Chrome |
Maybe this is because it first checks for support and otherwise falls back to a file input?
After looking at the code I was thinking it's actually because the rendering happens in this order:
- The component's
render
method creates a file input - In
componentDidMount
the component calls the Filepondcreate
method (see https://github.com/pqina/react-filepond/blob/master/lib/index.js#L53)
Thus the DOM has an unstyled input element in between these two things
PR is welcome
I thought about it a little but for my part I'm just going to work around this by moving it to a part of the UI where it isn't immediately visible. Here's my thoughts in case it helps someone else:
One option would be to hide the component until the Filepond create
process is complete. But that would just create a delayed load of the component--better than a flicker, but not perfect.
A real solution would be to fully create the desired DOM element(s) in the React render
method so it looks good when it is mounted. Maybe it's possible to render the Filepond into a detached DOM element and then convince React to render that (?). The alternative would be to actually render (parts of?) the Filepond UI using React.
Has this been addressed yet?
i did sth like this :
export default function FileUpload({ chatId, addDocument }: FileUploadProps) { registerPlugin(FilePondPluginFileValidateType) registerPlugin(FilePondPluginFileValidateSize);
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(true);
}, 100);
return () => clearTimeout(timer);
}, []);
return (
<div>
{isVisible && (
<FilePond
allowMultiple={false}
credits={false}
className={"w-64 mx-auto mt-8"}
acceptedFileTypes={['application/pdf']}
maxFileSize={'5MB'}
allowRevert={false}
server={
{
process: {
url: '/api/upload',
ondata: (data) => {
data.append('chat_id', chatId!);
return data;
},
onload: (response) => {
console.log(response);
const newDocument = JSON.parse(response);
addDocument(newDocument);
return response;
}
}
}
}
/>
)}
</div>
);
}