uploadcare / react-widget

Uploadcare React Widget
MIT License
85 stars 18 forks source link

Upload Panel, Validators and State Variables #377

Closed bent-belmark closed 1 year ago

bent-belmark commented 1 year ago

Describe the bug

When using validators and other events, updating state variables within events seems to break the upload panel.

Removing the state variable update in my code below causes things to work.. but as soon as I update a state variable from either an onProgress or onChange, the uploader breaks (does not show files when selected). No errors are logged to the console.

Removing the validation, the onChange or onProgress works with or without state variable changes. Validation works without the onChange/onProgress events touching state variables.. I'd like to be able to use full functionality!

This issue seems not to be valid using the widget, but the panel fits our needs while the widget does not.

Code / screenshots

import React from "react";
import './App.css';
import {Panel} from "@uploadcare/react-widget";

function App() {

  const [uploading, setUploading] = React.useState(false);

  const fileTypeLimit = (allowedFileTypes) => {
    const types = allowedFileTypes.split(' ');

    return function(fileInfo) {
      if (fileInfo.name === null) {
        return
      }
      const extension = fileInfo.name.split('.').pop()

      if (extension && !types.includes(extension.toLowerCase())) {
        throw new Error('fileType');
      }
    }
  }

  const validators = [fileTypeLimit('jpeg jpg png webp tiff gif bmp pcx tga heic heif zip ttf otf pdf ai svg psd indd eps zip')];

  const handleUploadProgress = (progress) => {
    if (progress.some( (p) => { return p.state == 'uploading' }) ) {
      setUploading(true);
    } else {
      setUploading(false);
    }
    return null;
  }

  return (
    <div className="App">

      <Panel publicKey={'put-your-pub-key-here'}
             multiple={true}
             tabs={'file url gdrive gphotos box dropbox onedrive'}
             validators={validators}
             onProgress={(progress) => handleUploadProgress(progress)}
      />
    </div>
  );
}

export default App;

Environment

nd0ut commented 1 year ago

Hey @bent-belmark, try to wrap your validators and progress callback into the useMemo and useCallback. Like this: https://codesandbox.io/s/happy-scooby-tcw60j?file=/src/App.js:773-784

bent-belmark commented 1 year ago

@nd0ut - That works, thanks!