react-widget icon indicating copy to clipboard operation
react-widget copied to clipboard

Remove file from widget after upload.

Open stevesizer opened this issue 4 years ago • 11 comments

I'm using the widget api to open the dialog and then on file change creating my object to save to the database. After I have uploaded the image I am trying to remove it from widget using the getInput function.

This is not removing the image. So when I go to reopen the widget the last image uploaded is in preview mode. ANy help would be appreciated. Here is my code below.

const fileChange = (fileInfo) => { let newAttachment = { name: fileInfo.name, file_type: fileInfo.mimeType, size: fileInfo.size, attachment_url: fileInfo.cdnUrl, };

let newMessage = { ...props.message };
newMessage.attachments_attributes.push(newAttachment);
props.updateAttachment(newMessage);
props.postMessage(conversation.id);
let fileInput = widgetApi.current.getInput();
fileInput.value = null;

};

stevesizer avatar Mar 26 '21 23:03 stevesizer

Hey @stevesizer You need to use value prop to reset the widget value. Here is the example sandbox - https://codesandbox.io/s/laughing-golick-f95t2?file=/src/App.js:0-523

const [value, setValue] = useState();

const onChange = (fileInfo) => {
  setValue(null);
};

<Widget
  value={value}
  publicKey="demopublickey"
  onChange={onChange}
/>

nd0ut avatar Mar 29 '21 11:03 nd0ut

I can't make this work:

  1. Value property type is string while onChange handler receives FileInfo
  2. Setting FileInfo as value is causing Incorrect value error

Mosquid avatar Nov 25 '21 08:11 Mosquid

you need to use separate state for you value of the widget to make it work.

stevesizer avatar Nov 25 '21 08:11 stevesizer

@stevesizer thanks for you quick response. Here's how I made it work:

const [value, setValue] = useState<FileInfo>();

const resetValue = () => {
  setValue();
};

...

{value && <img className="preview" src={value.cdnUrl} />}
<Widget
  value={value?.uuid ?? ""}
  onChange={setValue}
  ref={widgetRef}
  publicKey={UPLOADCARE_KEY}
/>

Mosquid avatar Nov 25 '21 08:11 Mosquid

It might be best to have some state for the image.

const [value, setValue] = useState();
const [imageUrl, setImageUrl] = useState(null);

const onChange = (fileInfo) => {
  setImageUrl(fileInfo.cdnUrl);
  setValue(null);
};

{imageUrl && <img className="preview" src={imageUrl} />}

<Widget
  value={value}
  publicKey="demopublickey"
  onChange={onChange}
/>

stevesizer avatar Nov 25 '21 08:11 stevesizer

@nd0ut Not sure if you'd prefer to resurrect an old question or open a new one, but I'm working on the same use case and notice that the example you provided (https://codesandbox.io/s/laughing-golick-f95t2?file=/src/App.js:0-523) only works once. The first upload is cleared, but after a second file is uploaded, the state persists.

This matches the behavior I'm seeing with my own project. How can we guarantee that the value is properly cleared out on every upload, instead of just the first?

line1 avatar Aug 31 '22 14:08 line1

Apologies for the unnecessary update to an old question - the issue was with value never getting set to a non-null value. Updating that state when the upload starts, then flipping back to null when done, was all it took to resolve this.

line1 avatar Aug 31 '22 15:08 line1

I have been using a self built widget for some years now. Seing this react widget I wanted to switch. Took me 10 minutes to rebuild.

Now I have been debugging this issue for a full hour. From the docs I have NO idea what the value is for. Nor how manipulating it would influence the behaviour.

All I want is that the button saying "Choose a file" never changes. Which seems the logical behaviour for a button.

But instead I get first this button: 1 (Below the button is a list. At the left it would show an image preview for image files)

And after clicking it and choosing a file this weirdo: 2

Why should the button suddenly mutate to a link and some information? For the life of me I can't figure out why this would make any sense.

I have tried introducing state and mutating it as mentioned above. Though it is above me to understand why this state should be necessary for a simple button. It did not work.

I have then tried to monkeypatch this widget by giving it an id and changing that on change to force re-initiating this widget. Not even that solved the issue!?

How can I achieve that the button stays a button?

I get the impression that this widget wants to achieve something very opinionated that is not explained. It would be much better to have it much more simple - just a button to add files.

barbalex avatar Sep 19 '22 19:09 barbalex

@barbalex I struggled with that for a while as well. I think it's because the Widget itself wants to "own" the list of files inside it, whereas it would be very useful to have a more React-y component that allowed us to control it from top to bottom.

wub avatar May 06 '23 01:05 wub

Hey guys, I agree that the value prop has a pretty strange behavior. It doesn't work as expected with controlled components, since it only calls widget.value() internally on changes. To empty the file list, you should pass an empty array instead of null. This is missing in the docs.

Therefore, I want to rename the value prop to defaultValue and ignore it after mounting. And to update the internal file list state, an imperative API should be used.

nd0ut avatar May 10 '23 09:05 nd0ut

I was able to clear the selected file more than once by randomizing the key prop to force React to re-mount the component:

const [key, setKey] = useState(0);
function onChange() {
  setKey(Math.random());
}
<Widget key={key} onChange={onChange} />

freejosh avatar Jul 20 '23 12:07 freejosh